diff options
Diffstat (limited to 'cpp/include/Ice')
-rw-r--r-- | cpp/include/Ice/AsyncResult.h | 258 | ||||
-rw-r--r-- | cpp/include/Ice/FactoryTable.h | 6 | ||||
-rw-r--r-- | cpp/include/Ice/FactoryTableInit.h | 33 | ||||
-rw-r--r-- | cpp/include/Ice/Incoming.h | 8 | ||||
-rw-r--r-- | cpp/include/Ice/IncomingAsync.h | 34 | ||||
-rw-r--r-- | cpp/include/Ice/IncomingAsyncF.h | 2 | ||||
-rw-r--r-- | cpp/include/Ice/Initialize.h | 2 | ||||
-rw-r--r-- | cpp/include/Ice/InputStream.h | 9 | ||||
-rw-r--r-- | cpp/include/Ice/OutgoingAsync.h | 786 | ||||
-rw-r--r-- | cpp/include/Ice/OutputStream.h | 9 | ||||
-rw-r--r-- | cpp/include/Ice/Proxy.h | 681 | ||||
-rw-r--r-- | cpp/include/Ice/ProxyF.h | 57 | ||||
-rw-r--r-- | cpp/include/Ice/StreamHelpers.h | 76 | ||||
-rw-r--r-- | cpp/include/Ice/Traits.h | 21 | ||||
-rw-r--r-- | cpp/include/Ice/VirtualShared.h | 10 |
15 files changed, 1198 insertions, 794 deletions
diff --git a/cpp/include/Ice/AsyncResult.h b/cpp/include/Ice/AsyncResult.h index 35c307f0d27..f58c214742b 100644 --- a/cpp/include/Ice/AsyncResult.h +++ b/cpp/include/Ice/AsyncResult.h @@ -10,93 +10,51 @@ #ifndef ICE_ASYNC_RESULT_H #define ICE_ASYNC_RESULT_H +#ifndef ICE_CPP11_MAPPING + #include <IceUtil/Monitor.h> #include <IceUtil/Mutex.h> -#include <IceUtil/UniquePtr.h> #include <Ice/LocalObject.h> #include <Ice/CommunicatorF.h> #include <Ice/ConnectionF.h> #include <Ice/ProxyF.h> -#include <Ice/InstanceF.h> -#include <Ice/RequestHandlerF.h> #include <Ice/AsyncResultF.h> -#include <Ice/ObserverHelper.h> -#include <Ice/InputStream.h> -#include <Ice/VirtualShared.h> - -namespace IceInternal -{ - -class CallbackBase; -ICE_DEFINE_PTR(CallbackBasePtr, CallbackBase); - -} namespace Ice { -class ICE_API AsyncResult : private IceUtil::noncopyable, -#ifdef ICE_CPP11_MAPPING - public ::std::enable_shared_from_this<::Ice::AsyncResult> -#else - public Ice::LocalObject -#endif +class ICE_API AsyncResult : private IceUtil::noncopyable, public Ice::LocalObject { public: - -#ifdef ICE_CPP11_MAPPING - AsyncResult(const CommunicatorPtr&, const IceInternal::InstancePtr&, const std::string&, - const IceInternal::CallbackBasePtr&); -#else - AsyncResult(const CommunicatorPtr&, const IceInternal::InstancePtr&, const std::string&, - const IceInternal::CallbackBasePtr&, const LocalObjectPtr&); -#endif - virtual ~AsyncResult(); // Must be heap-allocated - void cancel(); + virtual void cancel() = 0; - Int getHash() const; + virtual Int getHash() const = 0; - CommunicatorPtr getCommunicator() const; - virtual ConnectionPtr getConnection() const; - virtual ObjectPrxPtr getProxy() const; + virtual CommunicatorPtr getCommunicator() const = 0; + virtual ConnectionPtr getConnection() const = 0; + virtual ObjectPrxPtr getProxy() const = 0; - bool isCompleted() const; - void waitForCompleted(); + virtual bool isCompleted() const = 0; + virtual void waitForCompleted() = 0; - bool isSent() const; - void waitForSent(); + virtual bool isSent() const = 0; + virtual void waitForSent() = 0; - void throwLocalException() const; + virtual void throwLocalException() const = 0; - bool sentSynchronously() const; + virtual bool sentSynchronously() const = 0; -#ifndef ICE_CPP11_MAPPING - LocalObjectPtr getCookie() const; -#endif - - const std::string& getOperation() const; + virtual LocalObjectPtr getCookie() const = 0; - ::Ice::InputStream* __startReadParams() - { - _is.startEncapsulation(); - return &_is; - } - void __endReadParams() - { - _is.endEncapsulation(); - } - void __readEmptyParams() - { - _is.skipEmptyEncapsulation(); - } - void __readParamEncaps(const ::Ice::Byte*& encaps, ::Ice::Int& sz) - { - _is.readEncapsulation(encaps, sz); - } - void __throwUserException(); + virtual const std::string& getOperation() const = 0; - bool __wait(); + virtual bool __wait() = 0; + virtual Ice::InputStream* __startReadParams() = 0; + virtual void __endReadParams() = 0; + virtual void __readEmptyParams() = 0; + virtual void __readParamEncaps(const ::Ice::Byte*&, ::Ice::Int&) = 0; + virtual void __throwUserException() = 0; static void __check(const AsyncResultPtr&, const ::IceProxy::Ice::Object*, const ::std::string&); static void __check(const AsyncResultPtr&, const Connection*, const ::std::string&); @@ -105,182 +63,10 @@ public: protected: static void __check(const AsyncResultPtr&, const ::std::string&); - - bool sent(bool); - bool finished(bool); - bool finished(const Exception&); - - void invokeSentAsync(); - void invokeCompletedAsync(); - - void invokeSent(); - void invokeCompleted(); - - void cancel(const LocalException&); - virtual void cancelable(const IceInternal::CancellationHandlerPtr&); - void checkCanceled(); - - void warning(const std::exception&) const; - void warning() const; - - // - // This virtual method is necessary for the communicator flush - // batch requests implementation. - // - virtual IceInternal::InvocationObserver& getObserver() - { - return _observer; - } - - const IceInternal::InstancePtr _instance; - IceInternal::InvocationObserver _observer; - Ice::ConnectionPtr _cachedConnection; - bool _sentSynchronously; - - Ice::InputStream _is; - - IceUtil::Monitor<IceUtil::Mutex> _monitor; - -private: - - const CommunicatorPtr _communicator; - const std::string& _operation; - const IceInternal::CallbackBasePtr _callback; - const LocalObjectPtr _cookie; -#ifdef ICE_CPP11_MAPPING - std::exception_ptr _exception; -#else - IceUtil::UniquePtr<Exception> _exception; -#endif - - IceInternal::CancellationHandlerPtr _cancellationHandler; -#ifdef ICE_CPP11_MAPPING - std::exception_ptr _cancellationException; -#else - IceUtil::UniquePtr<Ice::LocalException> _cancellationException; -#endif - - static const unsigned char OK; - static const unsigned char Done; - static const unsigned char Sent; - static const unsigned char EndCalled; - static const unsigned char Canceled; - unsigned char _state; -}; - -} - -namespace IceInternal -{ - -// -// Base class for all callbacks. -// -class ICE_API CallbackBase : public Ice::EnableSharedFromThis<CallbackBase> -{ -public: - - void checkCallback(bool, bool); - - virtual void completed(const ::Ice::AsyncResultPtr&) const = 0; -#ifndef ICE_CPP11_MAPPING - virtual CallbackBasePtr verify(const ::Ice::LocalObjectPtr&) = 0; -#endif - virtual void sent(const ::Ice::AsyncResultPtr&) const = 0; - virtual bool hasSentCallback() const = 0; -}; - -// -// Base class for generic callbacks. -// -class ICE_API GenericCallbackBase : public virtual CallbackBase -{ -}; - -// -// See comments in OutgoingAsync.cpp -// -extern ICE_API CallbackBasePtr __dummyCallback; - -// -// Generic callback template that requires the caller to down-cast the -// proxy and the cookie that are obtained from the AsyncResult. -// -template<class T> -class AsyncCallback : public GenericCallbackBase -{ -public: - - typedef T callback_type; - typedef IceUtil::Handle<T> TPtr; - - typedef void (T::*Callback)(const ::Ice::AsyncResultPtr&); - - AsyncCallback(const TPtr& instance, Callback cb, Callback sentcb = 0) : - _callback(instance), _completed(cb), _sent(sentcb) - { - checkCallback(instance, cb != 0); - } - - virtual void completed(const ::Ice::AsyncResultPtr& result) const - { - (_callback.get()->*_completed)(result); - } - - virtual CallbackBasePtr verify(const ::Ice::LocalObjectPtr&) - { - return this; // Nothing to do, the cookie is not type-safe. - } - - virtual void sent(const ::Ice::AsyncResultPtr& result) const - { - if(_sent) - { - (_callback.get()->*_sent)(result); - } - } - - virtual bool hasSentCallback() const - { - return _sent != 0; - } - -private: - - TPtr _callback; - Callback _completed; - Callback _sent; }; } -namespace Ice -{ - -#ifndef ICE_CPP11_MAPPING -typedef IceUtil::Handle< ::IceInternal::GenericCallbackBase> CallbackPtr; - -template<class T> CallbackPtr -newCallback(const IceUtil::Handle<T>& instance, - void (T::*cb)(const AsyncResultPtr&), - void (T::*sentcb)(const AsyncResultPtr&) = 0) -{ - return new ::IceInternal::AsyncCallback<T>(instance, cb, sentcb); -} - -template<class T> CallbackPtr -newCallback(T* instance, - void (T::*cb)(const AsyncResultPtr&), - void (T::*sentcb)(const AsyncResultPtr&) = 0) -{ - return new ::IceInternal::AsyncCallback<T>(instance, cb, sentcb); -} - #endif -} - -// -// Operation callbacks are specified in Proxy.h -// #endif diff --git a/cpp/include/Ice/FactoryTable.h b/cpp/include/Ice/FactoryTable.h index 03362685c43..24fb649d053 100644 --- a/cpp/include/Ice/FactoryTable.h +++ b/cpp/include/Ice/FactoryTable.h @@ -38,11 +38,7 @@ public: Ice::UserExceptionFactoryPtr getExceptionFactory(const ::std::string&) const; void removeExceptionFactory(const ::std::string&); -#ifdef ICE_CPP11_MAPPING - void addValueFactory(const ::std::string&, ::std::function<::Ice::ValuePtr (::std::string)>); -#else - void addValueFactory(const ::std::string&, const ::Ice::ValueFactoryPtr&); -#endif + void addValueFactory(const ::std::string&, ICE_IN(ICE_VALUE_FACTORY)); ICE_VALUE_FACTORY getValueFactory(const ::std::string&) const; void removeValueFactory(const ::std::string&); diff --git a/cpp/include/Ice/FactoryTableInit.h b/cpp/include/Ice/FactoryTableInit.h index 51660970d1d..4ded5bb725b 100644 --- a/cpp/include/Ice/FactoryTableInit.h +++ b/cpp/include/Ice/FactoryTableInit.h @@ -34,10 +34,10 @@ class ICE_API CompactIdInit public: CompactIdInit(const char*, int); - ~CompactIdInit(); private: + const int _compactId; }; @@ -46,19 +46,17 @@ class DefaultUserExceptionFactoryInit { public: - DefaultUserExceptionFactoryInit(const char* typeId) : - _typeId(typeId) + DefaultUserExceptionFactoryInit(const char* tId) : typeId(tId) { - factoryTable->addExceptionFactory(_typeId, new DefaultUserExceptionFactory<E>(_typeId)); + factoryTable->addExceptionFactory(typeId, new DefaultUserExceptionFactory<E>(typeId)); } ~DefaultUserExceptionFactoryInit() { - factoryTable->removeExceptionFactory(_typeId); + factoryTable->removeExceptionFactory(typeId); } -private: - const ::std::string _typeId; + const ::std::string typeId; }; template<class O> @@ -66,28 +64,25 @@ class DefaultValueFactoryInit { public: - DefaultValueFactoryInit(const char* typeId) : - _typeId(typeId) + DefaultValueFactoryInit(const char* tId) : typeId(tId) { #ifdef ICE_CPP11_MAPPING - factoryTable->addValueFactory(_typeId, - [](const std::string&) - { - return ::std::make_shared<O>(); - }); + factoryTable->addValueFactory(typeId, + [](const std::string&) + { + return ::std::make_shared<O>(); + }); #else - factoryTable->addValueFactory(_typeId, new DefaultValueFactory<O>(_typeId)); + factoryTable->addValueFactory(typeId, new DefaultValueFactory<O>(typeId)); #endif } ~DefaultValueFactoryInit() { - factoryTable->removeValueFactory(_typeId); + factoryTable->removeValueFactory(typeId); } -private: - const ::std::string _typeId; - + const ::std::string typeId; }; } diff --git a/cpp/include/Ice/Incoming.h b/cpp/include/Ice/Incoming.h index d95fb113731..d3637328a5d 100644 --- a/cpp/include/Ice/Incoming.h +++ b/cpp/include/Ice/Incoming.h @@ -41,7 +41,7 @@ public: protected: - IncomingBase(Instance*, ResponseHandler*, Ice::Connection*, const Ice::ObjectAdapterPtr&, bool, Ice::Byte, + IncomingBase(Instance*, ResponseHandler*, Ice::Connection*, const Ice::ObjectAdapterPtr&, bool, Ice::Byte, Ice::Int); IncomingBase(IncomingBase&); // Adopts the argument. It must not be used afterwards. @@ -91,8 +91,8 @@ public: void pop(); void startOver(); void killAsync(); - void setActive(IncomingAsync&); - + void setActive(IncomingAsyncPtr); + bool isRetriable() { return _inParamPos != 0; @@ -126,7 +126,7 @@ public: private: Ice::InputStream* _is; - + IncomingAsyncPtr _cb; Ice::Byte* _inParamPos; }; diff --git a/cpp/include/Ice/IncomingAsync.h b/cpp/include/Ice/IncomingAsync.h index 9221c1c12a2..52c5ab2b0c1 100644 --- a/cpp/include/Ice/IncomingAsync.h +++ b/cpp/include/Ice/IncomingAsync.h @@ -42,10 +42,25 @@ class ICE_API IncomingAsync : public IncomingBase, public virtual Ice::AMDCallback #endif { +#ifdef ICE_CPP11_MAPPING +public: + + // + // The constructor is public but it shouldn't be used directly, use create() instead. + // + IncomingAsync(Incoming&); + + static IncomingAsyncPtr create(Incoming&); // Adopts the argument. It must not be used afterwards. + +#else + +protected: + + IncomingAsync(Incoming&); +#endif + public: - - void __deactivate(Incoming&); virtual void ice_exception(const ::std::exception&); @@ -57,15 +72,6 @@ public: bool __validateResponse(bool); -#ifdef ICE_CPP11_MAPPING - static IncomingAsyncPtr create(Incoming&); // Adopts the argument. It must not be used afterwards. - -protected: - - IncomingAsync(Incoming&); // Adopts the argument. It must not be used afterwards. -#else - IncomingAsync(Incoming&); // Adopts the argument. It must not be used afterwards. -#endif private: // @@ -93,7 +99,7 @@ namespace Ice class ICE_API AMD_Object_ice_invoke : public virtual Ice::AMDCallback { public: - + virtual void ice_response(bool, const std::vector<Ice::Byte>&) = 0; virtual void ice_response(bool, const std::pair<const Ice::Byte*, const Ice::Byte*>&) = 0; }; @@ -109,9 +115,9 @@ namespace Ice class ICE_API AMD_Object_ice_invoke : public ::Ice::AMD_Object_ice_invoke, public IceInternal::IncomingAsync { public: - + AMD_Object_ice_invoke(IceInternal::Incoming&); - + virtual void ice_response(bool, const std::vector< ::Ice::Byte>&); virtual void ice_response(bool, const std::pair<const ::Ice::Byte*, const ::Ice::Byte*>&); }; diff --git a/cpp/include/Ice/IncomingAsyncF.h b/cpp/include/Ice/IncomingAsyncF.h index c315e584ebc..a30bcb19425 100644 --- a/cpp/include/Ice/IncomingAsyncF.h +++ b/cpp/include/Ice/IncomingAsyncF.h @@ -17,8 +17,10 @@ #ifdef ICE_CPP11_MAPPING namespace IceInternal { + class IncomingAsync; typedef std::shared_ptr<IncomingAsync> IncomingAsyncPtr; + }; #else namespace IceInternal diff --git a/cpp/include/Ice/Initialize.h b/cpp/include/Ice/Initialize.h index 6b060f07106..c1757ce6c19 100644 --- a/cpp/include/Ice/Initialize.h +++ b/cpp/include/Ice/Initialize.h @@ -133,7 +133,7 @@ public: #else CommunicatorHolder(const CommunicatorPtr&); - + // Required for successful copy-initialization, but not // defined as it should always be elided by compiler CommunicatorHolder(const CommunicatorHolder&); diff --git a/cpp/include/Ice/InputStream.h b/cpp/include/Ice/InputStream.h index 0e1aea08587..b903f955b82 100644 --- a/cpp/include/Ice/InputStream.h +++ b/cpp/include/Ice/InputStream.h @@ -24,7 +24,6 @@ #include <Ice/UserExceptionFactory.h> #include <Ice/StreamHelpers.h> #include <Ice/FactoryTable.h> -#include <Ice/Traits.h> namespace Ice { @@ -362,13 +361,13 @@ public: template<typename T> void read(Int tag, IceUtil::Optional<T>& v) { if(readOpt(tag, StreamOptionalHelper<T, - StreamableTraits<T>::helper, - StreamableTraits<T>::fixedLength>::optionalFormat)) + StreamableTraits<T>::helper, + StreamableTraits<T>::fixedLength>::optionalFormat)) { v.__setIsSet(); StreamOptionalHelper<T, - StreamableTraits<T>::helper, - StreamableTraits<T>::fixedLength>::read(this, *v); + StreamableTraits<T>::helper, + StreamableTraits<T>::fixedLength>::read(this, *v); } else { diff --git a/cpp/include/Ice/OutgoingAsync.h b/cpp/include/Ice/OutgoingAsync.h index afcfc1d7fcc..3b61fd7be52 100644 --- a/cpp/include/Ice/OutgoingAsync.h +++ b/cpp/include/Ice/OutgoingAsync.h @@ -11,12 +11,23 @@ #define ICE_OUTGOING_ASYNC_H #include <IceUtil/Timer.h> +#include <IceUtil/Monitor.h> #include <Ice/OutgoingAsyncF.h> -#include <Ice/AsyncResult.h> #include <Ice/CommunicatorF.h> #include <Ice/ConnectionIF.h> #include <Ice/ObjectAdapterF.h> +#include <Ice/VirtualShared.h> +#include <Ice/RequestHandlerF.h> +#include <Ice/ConnectionF.h> #include <Ice/OutputStream.h> +#include <Ice/InputStream.h> +#include <Ice/ObserverHelper.h> +#include <Ice/LocalException.h> + +#ifndef ICE_CPP11_MAPPING +# include <Ice/AsyncResult.h> +# include <IceUtil/UniquePtr.h> +#endif #include <exception> @@ -26,25 +37,74 @@ namespace IceInternal class RetryException; class CollocatedRequestHandler; +class ICE_API OutgoingAsyncCompletionCallback +{ +protected: + + virtual bool handleSent(bool, bool) = 0; + virtual bool handleException(const Ice::Exception&) = 0; + virtual bool handleResponse(bool) = 0; + + virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const = 0; + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const = 0; + virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const = 0; +}; + // // Base class for handling asynchronous invocations. This class is // responsible for the handling of the output stream and the child // invocation observer. // -class ICE_API OutgoingAsyncBase : public Ice::AsyncResult +class ICE_API OutgoingAsyncBase : virtual public OutgoingAsyncCompletionCallback, +#ifndef ICE_CPP11_MAPPING + public Ice::AsyncResult, +#endif + public Ice::EnableSharedFromThis<OutgoingAsyncBase> { public: virtual bool sent(); - virtual bool completed(const Ice::Exception&); - virtual bool completed(); + virtual bool exception(const Ice::Exception&); + virtual bool response(); + + void invokeSentAsync(); + void invokeExceptionAsync(); + void invokeResponseAsync(); + + void invokeSent(); + void invokeException(); + void invokeResponse(); + + virtual void cancelable(const IceInternal::CancellationHandlerPtr&); + void cancel(); + +#ifndef ICE_CPP11_MAPPING + virtual Ice::Int getHash() const; + + virtual Ice::CommunicatorPtr getCommunicator() const; + virtual Ice::ConnectionPtr getConnection() const; + virtual Ice::ObjectPrx getProxy() const; + + virtual Ice::LocalObjectPtr getCookie() const; + virtual const std::string& getOperation() const; + + virtual bool isCompleted() const; + virtual void waitForCompleted(); + + virtual bool isSent() const; + virtual void waitForSent(); - // Those methods are public when called from an OutgoingAsyncBase reference. - using Ice::AsyncResult::cancelable; - using Ice::AsyncResult::invokeSent; - using Ice::AsyncResult::invokeSentAsync; - using Ice::AsyncResult::invokeCompleted; - using Ice::AsyncResult::invokeCompletedAsync; + virtual bool sentSynchronously() const; + + virtual void throwLocalException() const; + + virtual bool __wait(); + virtual Ice::InputStream* __startReadParams(); + virtual void __endReadParams(); + virtual void __readEmptyParams(); + virtual void __readParamEncaps(const ::Ice::Byte*&, ::Ice::Int&); + virtual void __throwUserException(); +#endif void attachRemoteObserver(const Ice::ConnectionInfoPtr& c, const Ice::EndpointPtr& endpt, Ice::Int requestId) { @@ -63,22 +123,67 @@ public: return &_os; } - virtual Ice::InputStream* getIs(); + Ice::InputStream* getIs() + { + return &_is; + } protected: + OutgoingAsyncBase(const InstancePtr&); + + bool sentImpl(bool); + bool exceptionImpl(const Ice::Exception&); + bool responseImpl(bool); + + void cancel(const Ice::LocalException&); + void checkCanceled(); + + void warning(const std::exception&) const; + void warning() const; + + // + // This virtual method is necessary for the communicator flush + // batch requests implementation. + // + virtual IceInternal::InvocationObserver& getObserver() + { + return _observer; + } + + const InstancePtr _instance; + Ice::ConnectionPtr _cachedConnection; + bool _sentSynchronously; + bool _doneInSent; + unsigned char _state; + #ifdef ICE_CPP11_MAPPING - OutgoingAsyncBase(const Ice::CommunicatorPtr&, const InstancePtr&, const std::string&, const CallbackBasePtr&); + std::mutex _m; + using Lock = std::lock_guard<std::mutex>; + std::exception_ptr _ex; + std::exception_ptr _cancellationException; #else - OutgoingAsyncBase(const Ice::CommunicatorPtr&, const InstancePtr&, const std::string&, const CallbackBasePtr&, - const Ice::LocalObjectPtr&); + IceUtil::Monitor<IceUtil::Mutex> _m; + typedef IceUtil::Monitor<IceUtil::Mutex>::Lock Lock; + IceUtil::UniquePtr<Ice::Exception> _ex; + IceUtil::UniquePtr<Ice::LocalException> _cancellationException; + Ice::LocalObjectPtr _cookie; #endif - bool sent(bool); - bool finished(const Ice::Exception&); + InvocationObserver _observer; ObserverHelperT<Ice::Instrumentation::ChildInvocationObserver> _childObserver; Ice::OutputStream _os; + Ice::InputStream _is; + + CancellationHandlerPtr _cancellationHandler; + + static const unsigned char OK; + static const unsigned char Sent; +#ifndef ICE_CPP11_MAPPING + static const unsigned char Done; + static const unsigned char EndCalled; +#endif }; // @@ -87,38 +192,39 @@ protected: // correct notified of failures and make sure the retry task is // correctly canceled when the invocation completes. // -class ICE_API ProxyOutgoingAsyncBase : public OutgoingAsyncBase, public IceUtil::TimerTask +class ICE_API ProxyOutgoingAsyncBase : public OutgoingAsyncBase, + public IceUtil::TimerTask, + public Ice::EnableSharedFromThis<ProxyOutgoingAsyncBase> { public: virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool) = 0; virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*) = 0; - virtual Ice::ObjectPrxPtr getProxy() const; - - using OutgoingAsyncBase::sent; - virtual bool completed(const Ice::Exception&); - void retryException(const Ice::Exception&); + virtual bool exception(const Ice::Exception&); virtual void cancelable(const CancellationHandlerPtr&); + void retryException(const Ice::Exception&); void retry(); void abort(const Ice::Exception&); -protected: + using Ice::EnableSharedFromThis<ProxyOutgoingAsyncBase>::shared_from_this; -#ifdef ICE_CPP11_MAPPING - ProxyOutgoingAsyncBase(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&); -#else - ProxyOutgoingAsyncBase(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&, - const Ice::LocalObjectPtr&); +#ifndef ICE_CPP11_MAPPING + virtual Ice::ObjectPrx getProxy() const; + virtual Ice::CommunicatorPtr getCommunicator() const; #endif - void invokeImpl(bool); - bool sent(bool); - bool finished(const Ice::Exception&); - bool finished(bool); +protected: + + ProxyOutgoingAsyncBase(const Ice::ObjectPrxPtr&); + ~ProxyOutgoingAsyncBase(); + + void invokeImpl(bool); + bool sentImpl(bool); + bool exceptionImpl(const Ice::Exception&); + bool responseImpl(bool); - int handleException(const Ice::Exception&); virtual void runTimerTask(); const Ice::ObjectPrxPtr _proxy; @@ -138,24 +244,23 @@ class ICE_API OutgoingAsync : public ProxyOutgoingAsyncBase { public: -#ifdef ICE_CPP11_MAPPING - OutgoingAsync(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&); -#else - OutgoingAsync(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&, const Ice::LocalObjectPtr&); -#endif + OutgoingAsync(const Ice::ObjectPrxPtr&); + void prepare(const std::string&, Ice::OperationMode, const Ice::Context&); virtual bool sent(); + virtual bool response(); virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool); virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*); - using ProxyOutgoingAsyncBase::completed; - virtual bool completed(); - void abort(const Ice::Exception&); - - void invoke(); + void invoke(const std::string&); +#ifdef ICE_CPP11_MAPPING + void invoke(const std::string&, Ice::OperationMode, Ice::FormatType, const Ice::Context&, + const std::function<void (Ice::OutputStream*)>&); + void throwUserException(); +#endif Ice::OutputStream* startWriteParams(Ice::FormatType format) { @@ -182,14 +287,15 @@ public: } } - virtual Ice::InputStream* getIs() - { - return &_is; - } - -private: +protected: const Ice::EncodingVersion _encoding; + +#ifdef ICE_CPP11_MAPPING + std::function<void (const ::Ice::UserException&)> _userException; +#endif + + bool _synchronous; }; // @@ -199,16 +305,12 @@ class ICE_API ProxyFlushBatchAsync : public ProxyOutgoingAsyncBase { public: -#ifdef ICE_CPP11_MAPPING - ProxyFlushBatchAsync(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&); -#else - ProxyFlushBatchAsync(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&, const Ice::LocalObjectPtr&); -#endif + ProxyFlushBatchAsync(const Ice::ObjectPrxPtr&); virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool); virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*); - void invoke(); + void invoke(const std::string&); private: @@ -223,15 +325,12 @@ class ICE_API ProxyGetConnection : public ProxyOutgoingAsyncBase { public: -#ifdef ICE_CPP11_MAPPING - ProxyGetConnection(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&); -#else - ProxyGetConnection(const Ice::ObjectPrxPtr&, const std::string&, const CallbackBasePtr&, const Ice::LocalObjectPtr&); -#endif + ProxyGetConnection(const Ice::ObjectPrxPtr&); + virtual AsyncStatus invokeRemote(const Ice::ConnectionIPtr&, bool, bool); virtual AsyncStatus invokeCollocated(CollocatedRequestHandler*); - void invoke(); + void invoke(const std::string&); }; typedef IceUtil::Handle<ProxyGetConnection> ProxyGetConnectionPtr; @@ -242,16 +341,11 @@ class ICE_API ConnectionFlushBatchAsync : public OutgoingAsyncBase { public: -#ifdef ICE_CPP11_MAPPING - ConnectionFlushBatchAsync(const Ice::ConnectionIPtr&, const Ice::CommunicatorPtr&, const InstancePtr&, - const std::string&, const CallbackBasePtr&); -#else - ConnectionFlushBatchAsync(const Ice::ConnectionIPtr&, const Ice::CommunicatorPtr&, const InstancePtr&, - const std::string&, const CallbackBasePtr&, const Ice::LocalObjectPtr&); -#endif + ConnectionFlushBatchAsync(const Ice::ConnectionIPtr&, const InstancePtr&); + virtual Ice::ConnectionPtr getConnection() const; - void invoke(); + void invoke(const std::string&); private: @@ -262,122 +356,524 @@ typedef IceUtil::Handle<ConnectionFlushBatchAsync> ConnectionFlushBatchAsyncPtr; // // Class for handling Ice::Communicator::begin_flushBatchRequests // -class ICE_API CommunicatorFlushBatchAsync : public Ice::AsyncResult +class ICE_API CommunicatorFlushBatchAsync : public OutgoingAsyncBase, + public Ice::EnableSharedFromThis<CommunicatorFlushBatchAsync> { public: -#ifdef ICE_CPP11_MAPPING - CommunicatorFlushBatchAsync(const Ice::CommunicatorPtr&, const InstancePtr&, const std::string&, - const CallbackBasePtr&); -#else - CommunicatorFlushBatchAsync(const Ice::CommunicatorPtr&, const InstancePtr&, const std::string&, - const CallbackBasePtr&, const Ice::LocalObjectPtr&); -#endif + CommunicatorFlushBatchAsync(const InstancePtr&); void flushConnection(const Ice::ConnectionIPtr&); - void ready(); + void invoke(const std::string&); + + using Ice::EnableSharedFromThis<CommunicatorFlushBatchAsync>::shared_from_this; private: void check(bool); int _useCount; + InvocationObserver _observer; }; } +namespace IceInternal +{ + +#ifdef ICE_CPP11_MAPPING + +class ICE_API LambdaInvoke : virtual public OutgoingAsyncCompletionCallback +{ +public: + + LambdaInvoke(std::function<void (::std::exception_ptr)>&& exception, std::function<void (bool)>&& sent) : + _exception(move(exception)), _sent(move(sent)) + { + } + +protected: + + virtual bool handleSent(bool, bool) override; + virtual bool handleException(const Ice::Exception&) override; + virtual bool handleResponse(bool) override; + + virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const override; + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const override; + virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const override; + + std::function<void (::std::exception_ptr)> _exception; + std::function<void (bool)> _sent; + std::function<void (bool)> _response; +}; + +template<typename Promise> +class PromiseInvoke : virtual public OutgoingAsyncCompletionCallback +{ +public: + + auto + getFuture() -> decltype(std::declval<Promise>().get_future()) + { + return _promise.get_future(); + } + +protected: + + Promise _promise; + std::function<void (bool)> _response; + +private: + + virtual bool handleSent(bool, bool) override + { + return false; + } + + virtual bool handleException(const Ice::Exception& ex) override + { + try + { + ex.ice_throw(); + } + catch(const Ice::Exception&) + { + _promise.set_exception(std::current_exception()); + } + return false; + } + + virtual bool handleResponse(bool ok) override + { + _response(ok); + return false; + } + + virtual void handleInvokeSent(bool, OutgoingAsyncBase*) const override + { + assert(false); + } + + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase*) const override + { + assert(false); + } + + virtual void handleInvokeResponse(bool, OutgoingAsyncBase*) const override + { + assert(false); + } +}; + +template<typename T> +class OutgoingAsyncT : public OutgoingAsync +{ +public: + + using OutgoingAsync::OutgoingAsync; + + 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) + { + _read = [](Ice::InputStream* stream) + { + T v; + stream->read(v); + return v; + }; + _userException = userException; + OutgoingAsync::invoke(operation, mode, format, ctx, write); + } + + 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, + std::function<T (Ice::InputStream*)>&& read) + { + _read = read; + _userException = userException; + OutgoingAsync::invoke(operation, mode, format, ctx, write); + } + +protected: + + std::function<T (Ice::InputStream*)> _read; +}; + +template<> +class ICE_API OutgoingAsyncT<void> : public OutgoingAsync +{ +public: + + using OutgoingAsync::OutgoingAsync; + + 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 = userException; + OutgoingAsync::invoke(operation, mode, format, ctx, write); + } +}; + +template<typename R> +class LambdaOutgoing : public OutgoingAsyncT<R>, public LambdaInvoke +{ +public: + + LambdaOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy, + std::function<void (R)> response, + std::function<void (::std::exception_ptr)>& ex, + std::function<void (bool)>& sent) : + OutgoingAsyncT<R>(proxy), LambdaInvoke(std::move(ex), std::move(sent)) + { + if(response) + { + _response = [this, response](bool ok) + { + if(ok) + { + assert(this->_read); + this->_is.startEncapsulation(); + R v = this->_read(&this->_is); + this->_is.endEncapsulation(); + try + { + response(std::move(v)); + } + catch(...) + { + throw std::current_exception(); + } + } + else + { + this->throwUserException(); + } + }; + } + } +}; + +template<> +class ICE_API LambdaOutgoing<void> : public OutgoingAsyncT<void>, public LambdaInvoke +{ +public: + + LambdaOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy, + std::function<void()> response, + std::function<void (::std::exception_ptr)>& ex, + std::function<void (bool)>& sent) : + OutgoingAsyncT<void>(proxy), LambdaInvoke(std::move(ex), std::move(sent)) + { + if(response) + { + _response = [this, response](bool ok) + { + if(this->_is.b.empty()) + { + // + // 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. + // + try + { + response(); + } + catch(...) + { + throw std::current_exception(); + } + } + else if(ok) + { + this->_is.skipEmptyEncapsulation(); + try + { + response(); + } + catch(...) + { + throw std::current_exception(); + } + } + else + { + this->throwUserException(); + } + }; + } + } +}; + +template<typename P, typename R> +class PromiseOutgoing : public OutgoingAsyncT<R>, public PromiseInvoke<P> +{ +public: + + PromiseOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy, bool synchronous) : + OutgoingAsyncT<R>(proxy) + { + this->_synchronous = synchronous; + this->_response = [this](bool ok) + { + if(ok) + { + assert(this->_read); + this->_is.startEncapsulation(); + R v = this->_read(&this->_is); + this->_is.endEncapsulation(); + this->_promise.set_value(v); + } + else + { + this->throwUserException(); + } + }; + } +}; + +template<typename P> +class PromiseOutgoing<P, void> : public OutgoingAsyncT<void>, public PromiseInvoke<P> +{ +public: + + PromiseOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy, bool synchronous) : + OutgoingAsyncT<void>(proxy) + { + this->_synchronous = synchronous; + this->_response = [&](bool ok) + { + if(this->_is.b.empty()) + { + // + // 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. + // + this->_promise.set_value(); + } + else if(ok) + { + this->_is.skipEmptyEncapsulation(); + this->_promise.set_value(); + } + else + { + this->throwUserException(); + } + }; + } + + virtual bool handleSent(bool done, bool) override + { + if(done) + { + PromiseInvoke<P>::_promise.set_value(); + } + return false; + } +}; + +#else + // -// Base callback for C++11 mapping +// Base class for all callbacks. // -#ifdef ICE_CPP11_MAPPING -namespace IceInternal +class ICE_API CallbackBase : public IceUtil::Shared +{ +public: + + void checkCallback(bool, bool); + + virtual void completed(const ::Ice::AsyncResultPtr&) const = 0; + virtual IceUtil::Handle<CallbackBase> verify(const ::Ice::LocalObjectPtr&) = 0; + virtual void sent(const ::Ice::AsyncResultPtr&) const = 0; + virtual bool hasSentCallback() const = 0; +}; +typedef IceUtil::Handle<CallbackBase> CallbackBasePtr; + +// +// Base class for generic callbacks. +// +class ICE_API GenericCallbackBase : public virtual CallbackBase +{ +}; + +// +// See comments in OutgoingAsync.cpp +// +extern ICE_API CallbackBasePtr __dummyCallback; + +// +// Generic callback template that requires the caller to down-cast the +// proxy and the cookie that are obtained from the AsyncResult. +// +template<class T> +class AsyncCallback : public GenericCallbackBase { +public: + + typedef T callback_type; + typedef IceUtil::Handle<T> TPtr; + + typedef void (T::*Callback)(const ::Ice::AsyncResultPtr&); + + AsyncCallback(const TPtr& instance, Callback cb, Callback sentcb = 0) : + _callback(instance), _completed(cb), _sent(sentcb) + { + checkCallback(instance, cb != 0); + } -class ICE_API OnewayClosureCallback : public ::IceInternal::GenericCallbackBase + virtual void completed(const ::Ice::AsyncResultPtr& result) const + { + (_callback.get()->*_completed)(result); + } + + virtual CallbackBasePtr verify(const ::Ice::LocalObjectPtr&) + { + return this; // Nothing to do, the cookie is not type-safe. + } + + virtual void sent(const ::Ice::AsyncResultPtr& result) const + { + if(_sent) + { + (_callback.get()->*_sent)(result); + } + } + + virtual bool hasSentCallback() const + { + return _sent != 0; + } + +private: + + TPtr _callback; + Callback _completed; + Callback _sent; +}; + +class CallbackCompletion : virtual public OutgoingAsyncCompletionCallback { public: - OnewayClosureCallback(const std::string&, - const std::shared_ptr<Ice::ObjectPrx>&, - std::function<void ()>, - std::function<void (::std::exception_ptr)>, - std::function<void (bool)>); + CallbackCompletion(const CallbackBasePtr& cb, const Ice::LocalObjectPtr& cookie) : _callback(cb) + { + if(!_callback) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__); + } + const_cast<CallbackBasePtr&>(_callback) = _callback->verify(cookie); + } - virtual void - sent(const ::Ice::AsyncResultPtr&) const; + virtual bool handleSent(bool, bool alreadySent) + { + return _callback && _callback->hasSentCallback() && !alreadySent; + } - virtual bool - hasSentCallback() const; + virtual bool handleException(const Ice::Exception&) + { + return _callback; + } - virtual void - completed(const ::Ice::AsyncResultPtr&) const; + virtual bool handleResponse(bool) + { + return _callback; + } - static std::function<void ()> - invoke(const std::string&, - const std::shared_ptr<Ice::ObjectPrx>&, - Ice::OperationMode, - Ice::FormatType, - std::function<void (::Ice::OutputStream*)>, - std::function<void ()>, - std::function<void (::std::exception_ptr)>, - std::function<void (bool)>, - const Ice::Context&); + virtual void handleInvokeSent(bool, OutgoingAsyncBase* outAsync) const + { + _callback->sent(outAsync); + } + + virtual void handleInvokeException(const Ice::Exception&, OutgoingAsyncBase* outAsync) const + { + _callback->completed(outAsync); + } + + virtual void handleInvokeResponse(bool, OutgoingAsyncBase* outAsync) const + { + _callback->completed(outAsync); + } private: - const std::string& __name; - std::shared_ptr<Ice::ObjectPrx> __proxy; - std::function<void ()> __response; - std::function<void (::std::exception_ptr)> __exception; - std::function<void (bool)> __sent; + const CallbackBasePtr _callback; }; -class ICE_API TwowayClosureCallback : public ::IceInternal::GenericCallbackBase +class ICE_API CallbackOutgoing : public OutgoingAsync, public CallbackCompletion { public: - TwowayClosureCallback(const std::string&, - const std::shared_ptr<Ice::ObjectPrx>&, - bool, - std::function<void (::Ice::InputStream*)>, - std::function<void (const ::Ice::UserException&)>, - std::function<void (::std::exception_ptr)>, - std::function<void (bool)>); - - virtual void - sent(const ::Ice::AsyncResultPtr&) const; - - virtual bool - hasSentCallback() const; - - virtual void - completed(const ::Ice::AsyncResultPtr&) const; - - static std::function<void ()> - invoke(const std::string&, - const std::shared_ptr<Ice::ObjectPrx>&, - Ice::OperationMode, - Ice::FormatType, - std::function<void (::Ice::OutputStream*)>, - bool, - std::function<void (::Ice::InputStream*)>, - std::function<void (const ::Ice::UserException&)>, - std::function<void (::std::exception_ptr)>, - std::function<void (bool)>, - const Ice::Context&); + CallbackOutgoing(const Ice::ObjectPrx& proxy, + const std::string& operation, + const CallbackBasePtr& cb, + const Ice::LocalObjectPtr& cookie) : + OutgoingAsync(proxy), CallbackCompletion(cb, cookie), _operation(operation) + { + _cookie = cookie; + } + + virtual const std::string& + getOperation() const + { + return _operation; + } private: - const std::string& __name; - std::shared_ptr<Ice::ObjectPrx> __proxy; - bool __readEmptyParams; - std::function<void (::Ice::InputStream*)> __read; - std::function<void (const ::Ice::UserException&)> __userException; - std::function<void (::std::exception_ptr)> __exception; - std::function<void (bool)> __sent; + const std::string& _operation; }; +#endif + } + +#ifndef ICE_CPP11_MAPPING + +namespace Ice +{ + +typedef IceUtil::Handle< ::IceInternal::GenericCallbackBase> CallbackPtr; + +template<class T> CallbackPtr +newCallback(const IceUtil::Handle<T>& instance, + void (T::*cb)(const AsyncResultPtr&), + void (T::*sentcb)(const AsyncResultPtr&) = 0) +{ + return new ::IceInternal::AsyncCallback<T>(instance, cb, sentcb); +} + +template<class T> CallbackPtr +newCallback(T* instance, + void (T::*cb)(const AsyncResultPtr&), + void (T::*sentcb)(const AsyncResultPtr&) = 0) +{ + return new ::IceInternal::AsyncCallback<T>(instance, cb, sentcb); +} + +} + +// +// Operation callbacks are specified in Proxy.h +// + #endif #endif diff --git a/cpp/include/Ice/OutputStream.h b/cpp/include/Ice/OutputStream.h index 74594f1dc25..5ba33bad8cc 100644 --- a/cpp/include/Ice/OutputStream.h +++ b/cpp/include/Ice/OutputStream.h @@ -20,7 +20,6 @@ #include <Ice/Protocol.h> #include <Ice/SlicedDataF.h> #include <Ice/StreamHelpers.h> -#include <Ice/Traits.h> namespace Ice { @@ -261,12 +260,12 @@ public: } if(writeOpt(tag, StreamOptionalHelper<T, - StreamableTraits<T>::helper, - StreamableTraits<T>::fixedLength>::optionalFormat)) + StreamableTraits<T>::helper, + StreamableTraits<T>::fixedLength>::optionalFormat)) { StreamOptionalHelper<T, - StreamableTraits<T>::helper, - StreamableTraits<T>::fixedLength>::write(this, *v); + StreamableTraits<T>::helper, + StreamableTraits<T>::fixedLength>::write(this, *v); } } diff --git a/cpp/include/Ice/Proxy.h b/cpp/include/Ice/Proxy.h index d9fce7f54df..058d3cfea7b 100644 --- a/cpp/include/Ice/Proxy.h +++ b/cpp/include/Ice/Proxy.h @@ -18,7 +18,7 @@ #include <Ice/RequestHandlerF.h> #include <Ice/EndpointF.h> #include <Ice/EndpointTypes.h> -#include <Ice/ObjectF.h> +#include <Ice/Object.h> #include <Ice/ObjectAdapterF.h> #include <Ice/ReferenceF.h> #include <Ice/BatchRequestQueueF.h> @@ -27,7 +27,7 @@ //#include <Ice/LocatorF.h> // Can't include RouterF.h here, otherwise we have cyclic includes #include <Ice/Current.h> #include <Ice/CommunicatorF.h> -#include <Ice/ObserverHelper.h> +#include <Ice/OutgoingAsync.h> #include <Ice/LocalException.h> #include <iosfwd> @@ -47,12 +47,191 @@ class Outgoing; namespace IceInternal { + template<typename P> ::std::shared_ptr<P> createProxy() { return ::std::shared_ptr<P>(new P()); } +inline ::std::pair<const Ice::Byte*, const Ice::Byte*> +makePair(const Ice::ByteSeq& seq) +{ + if(seq.empty()) + { + return { nullptr, nullptr }; + } + else + { + return { &seq[0], &seq[0] + seq.size() }; + } +} + +template<typename R> +class InvokeOutgoingAsyncT : public OutgoingAsync +{ +public: + + using OutgoingAsync::OutgoingAsync; + + void + invoke(const std::string& operation, + Ice::OperationMode mode, + const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& inParams, + const Ice::Context& ctx) + { + _read = [](bool ok, Ice::InputStream* stream) + { + const ::Ice::Byte* encaps; + ::Ice::Int sz; + stream->readEncapsulation(encaps, sz); + return R { ok, { encaps, encaps + sz } }; + }; + + try + { + prepare(operation, mode, ctx); + if(inParams.first == inParams.second) + { + _os.writeEmptyEncapsulation(_encoding); + } + else + { + _os.writeEncapsulation(inParams.first, static_cast<Ice::Int>(inParams.second - inParams.first)); + } + OutgoingAsync::invoke(operation); + } + catch(const Ice::Exception& ex) + { + abort(ex); + } + } + +protected: + + std::function<R (bool, Ice::InputStream*)> _read; +}; + +template<typename R> +class InvokeLambdaOutgoing : public InvokeOutgoingAsyncT<R>, public LambdaInvoke +{ +public: + + InvokeLambdaOutgoing(const ::std::shared_ptr<::Ice::ObjectPrx>& proxy, + ::std::function<void (R)> response, + ::std::function<void (::std::exception_ptr)>& ex, + ::std::function<void (bool)>& sent) : + InvokeOutgoingAsyncT<R>(proxy), LambdaInvoke(::std::move(ex), ::std::move(sent)) + { + if(response) + { + _response = [this, response](bool ok) + { + if(this->_is.b.empty()) + { + response(R { ok, { 0, 0 }}); + } + else + { + response(this->_read(ok, &this->_is)); + } + }; + } + } +}; + +template<typename P, typename R> +class InvokePromiseOutgoing : public InvokeOutgoingAsyncT<R>, public PromiseInvoke<P> +{ +public: + + InvokePromiseOutgoing(const std::shared_ptr<Ice::ObjectPrx>& proxy, bool synchronous) : + InvokeOutgoingAsyncT<R>(proxy) + { + this->_synchronous = synchronous; + this->_response = [this](bool ok) + { + if(this->_is.b.empty()) + { + this->_promise.set_value(R { ok, { 0, 0 }}); + } + else + { + this->_promise.set_value(this->_read(ok, &this->_is)); + } + }; + } + + virtual bool handleSent(bool done, bool) override + { + if(done) + { + this->_promise.set_value(R { true, { 0, 0 }}); + } + return false; + } +}; + +class ProxyGetConnectionLambda : public ProxyGetConnection, public LambdaInvoke +{ +public: + + ProxyGetConnectionLambda(const ::std::shared_ptr<::Ice::ObjectPrx>& proxy, + ::std::function<::std::shared_ptr<Ice::Connection>()> getConnection, + ::std::function<void (::std::shared_ptr<Ice::Connection>)> response, + ::std::function<void (::std::exception_ptr)>& ex, + ::std::function<void (bool)>& sent) : + ProxyGetConnection(proxy), LambdaInvoke(::std::move(ex), ::std::move(sent)) + { + _response = [response, getConnection](bool) + { + response(getConnection()); + }; + } +}; + +template<typename P> +class ProxyGetConnectionPromise : public ProxyGetConnection, public PromiseInvoke<P> +{ +public: + + ProxyGetConnectionPromise(const ::std::shared_ptr<::Ice::ObjectPrx>& proxy, + ::std::function<::std::shared_ptr<Ice::Connection>()> getConnection) : + ProxyGetConnection(proxy) + { + this->_response = [&, getConnection](bool) + { + this->_promise.set_value(getConnection()); + }; + } +}; + +class ProxyFlushBatchLambda : public ProxyFlushBatchAsync, public LambdaInvoke +{ +public: + + ProxyFlushBatchLambda(const ::std::shared_ptr<::Ice::ObjectPrx>& proxy, + ::std::function<void (::std::exception_ptr)>& ex, + ::std::function<void (bool)>& sent) : + ProxyFlushBatchAsync(proxy), LambdaInvoke(::std::move(ex), ::std::move(sent)) + { + } +}; + +template<typename P> +class ProxyFlushBatchPromise : public ProxyFlushBatchAsync, public PromiseInvoke<P> +{ +public: + + using ProxyFlushBatchAsync::ProxyFlushBatchAsync; + + virtual bool handleSent(bool, bool) override + { + this->_promise.set_value(_sentSynchronously); + return false; + } +}; + } namespace Ice @@ -81,287 +260,217 @@ public: ::std::string ice_toString() const; - bool ice_isA(const ::std::string& typeId, const ::Ice::Context& context = ::Ice::noExplicitContext); + bool + ice_isA(const ::std::string& typeId, const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + return makePromiseOutgoing<bool>(true, this, &ObjectPrx::__ice_isA, typeId, ctx).get(); + } ::std::function<void()> ice_isA_async(const ::std::string& typeId, ::std::function<void (bool)> response, - ::std::function<void (::std::exception_ptr)> = nullptr, + ::std::function<void (::std::exception_ptr)> ex = nullptr, ::std::function<void (bool)> sent = nullptr, - const ::Ice::Context& context = ::Ice::noExplicitContext); + const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + return makeLambdaOutgoing<bool>(response, ex, sent, this, &ObjectPrx::__ice_isA, typeId, ctx); + } - template<template<typename> class P = std::promise> - auto ice_isA_async(const ::std::string& typeId, const ::Ice::Context& context = ::Ice::noExplicitContext) + template<template<typename> class P = std::promise> auto + ice_isA_async(const ::std::string& typeId, const ::Ice::Context& ctx = ::Ice::noExplicitContext) -> decltype(std::declval<P<bool>>().get_future()) { - auto promise = ::std::make_shared<P<bool>>(); - - ice_isA_async( - typeId, - [promise](bool value) - { - promise->set_value(value); - }, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - nullptr, context); - - return promise->get_future(); + return makePromiseOutgoing<bool, P>(false, this, &ObjectPrx::__ice_isA, typeId, ctx); } void - ice_ping(const ::Ice::Context& context = ::Ice::noExplicitContext); + __ice_isA(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<bool>>&, const ::std::string&, const ::Ice::Context&); + + void + ice_ping(const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + makePromiseOutgoing(true, this, &ObjectPrx::__ice_ping, ctx).get(); + } ::std::function<void()> ice_ping_async(::std::function<void ()> response, - ::std::function<void (::std::exception_ptr)> exception = nullptr, + ::std::function<void (::std::exception_ptr)> ex = nullptr, ::std::function<void (bool)> sent = nullptr, - const ::Ice::Context& context = ::Ice::noExplicitContext); + const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + return makeLambdaOutgoing(response, ex, sent, this, &ObjectPrx::__ice_ping, ctx); + } template<template<typename> class P = std::promise> - auto ice_ping_async(const ::Ice::Context& context = ::Ice::noExplicitContext) + auto ice_ping_async(const ::Ice::Context& ctx = ::Ice::noExplicitContext) -> decltype(std::declval<P<void>>().get_future()) { - auto promise = ::std::make_shared<P<void>>(); - if(ice_isTwoway()) - { - ice_ping_async( - [promise]() - { - promise->set_value(); - }, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - nullptr, context); - } - else if(ice_isOneway() || ice_isDatagram()) - { - ice_ping_async( - nullptr, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - [promise](bool) - { - promise->set_value(); - }, - context); - } - else - { - ice_ping_async(nullptr, nullptr, nullptr, context); - promise->set_value(); - } - return promise->get_future(); + return makePromiseOutgoing<P>(false, this, &ObjectPrx::__ice_ping, ctx); } + void + __ice_ping(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<void>>&, const ::Ice::Context&); + ::std::vector<::std::string> - ice_ids(const ::Ice::Context& context = ::Ice::noExplicitContext); + ice_ids(const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + return makePromiseOutgoing<::std::vector<::std::string>>(true, this, &ObjectPrx::__ice_ids, ctx).get(); + } ::std::function<void()> - ice_ids_async(::std::function<void (::std::vector< ::std::string>)> response, - ::std::function<void (::std::exception_ptr)> exception = nullptr, + ice_ids_async(::std::function<void (::std::vector<::std::string>)> response, + ::std::function<void (::std::exception_ptr)> ex = nullptr, ::std::function<void (bool)> sent = nullptr, - const ::Ice::Context& context = ::Ice::noExplicitContext); + const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + return makeLambdaOutgoing<::std::vector<::std::string>>(response, ex, sent, this, &ObjectPrx::__ice_ids, ctx); + } - template<template<typename> class P = std::promise> - auto ice_ids_async(const ::Ice::Context& context = ::Ice::noExplicitContext) + template<template<typename> class P = std::promise> auto + ice_ids_async(const ::Ice::Context& ctx = ::Ice::noExplicitContext) -> decltype(std::declval<P<::std::vector<::std::string>>>().get_future()) { - auto promise = ::std::make_shared<P<::std::vector<::std::string>>>(); - ice_ids_async( - [promise](::std::vector<::std::string> ids) - { - promise->set_value(::std::move(ids)); - }, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - nullptr, context); - return promise->get_future(); + return makePromiseOutgoing<::std::vector<::std::string>, P>(false, this, &ObjectPrx::__ice_ids, ctx); } + void + __ice_ids(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::vector<::std::string>>>&, const ::Ice::Context&); + ::std::string - ice_id(const ::Ice::Context& context = ::Ice::noExplicitContext); + ice_id(const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + return makePromiseOutgoing<::std::string>(true, this, &ObjectPrx::__ice_id, ctx).get(); + } ::std::function<void ()> ice_id_async(::std::function<void (::std::string)> response, - ::std::function<void (::std::exception_ptr)> exception = nullptr, + ::std::function<void (::std::exception_ptr)> ex = nullptr, ::std::function<void (bool)> sent = nullptr, - const ::Ice::Context& context = ::Ice::noExplicitContext); + const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + return makeLambdaOutgoing<::std::string>(response, ex, sent, this, &ObjectPrx::__ice_id, ctx); + } template<template<typename> class P = std::promise> - auto ice_id_async(const ::Ice::Context& context = ::Ice::noExplicitContext) + auto ice_id_async(const ::Ice::Context& ctx = ::Ice::noExplicitContext) -> decltype(std::declval<P<::std::string>>().get_future()) { - auto promise = ::std::make_shared<P<::std::string>>(); - ice_id_async( - [promise](::std::string id) - { - promise->set_value(::std::move(id)); - }, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - nullptr, context); - return promise->get_future(); + return makePromiseOutgoing<::std::string, P>(false, this, &ObjectPrx::__ice_id, ctx); } + void + __ice_id(const ::std::shared_ptr<::IceInternal::OutgoingAsyncT<::std::string>>&, const ::Ice::Context&); + static const ::std::string& ice_staticId() { return ::Ice::Object::ice_staticId(); } + struct Result_ice_invoke + { + bool ok; + std::vector<::Ice::Byte> outParams; + }; + // Returns true if ok, false if user exception. bool ice_invoke(const ::std::string& operation, ::Ice::OperationMode mode, - const ::std::vector< ::Ice::Byte>& inParams, - ::std::vector< ::Ice::Byte>& outParams, - const ::Ice::Context& context = ::Ice::noExplicitContext); - + const ::std::vector< ::Ice::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*>& inParams, - ::std::vector< ::Ice::Byte>& outParams, - const ::Ice::Context& context = ::Ice::noExplicitContext); + const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& inP, + ::std::vector<::Ice::Byte>& outParams, + const ::Ice::Context& ctx = ::Ice::noExplicitContext) + { + 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; + } ::std::function<void ()> - ice_invoke_async( - const ::std::string&, - ::Ice::OperationMode, - const ::std::vector<::Ice::Byte>&, - ::std::function<void (bool, ::std::vector<::Ice::Byte>)> response, - ::std::function<void (::std::exception_ptr)> exception = nullptr, - ::std::function<void (bool)> sent = nullptr, - const ::Ice::Context& context = ::Ice::noExplicitContext); - - struct Result_invoke1 - { - bool ok; - std::vector<::Ice::Byte> outParams; - }; - - template<template<typename> class P = std::promise> - auto ice_invoke_async( - const ::std::string& operation, - ::Ice::OperationMode mode, - const ::std::vector<::Ice::Byte>& inParams, - const ::Ice::Context& context = ::Ice::noExplicitContext) - -> decltype(std::declval<P<Result_invoke1>>().get_future()) - { - auto promise = ::std::make_shared<P<Result_invoke1>>(); - if(ice_isTwoway()) + ice_invoke_async(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::vector<::Ice::Byte>& inP, + ::std::function<void (bool, ::std::vector<::Ice::Byte>)> response, + ::std::function<void (::std::exception_ptr)> ex = nullptr, + ::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; + if(response) { - ice_invoke_async(operation, mode, inParams, - [promise](bool ok, ::std::vector<::Ice::Byte> outParams) - { - Result_invoke1 result = {ok, move(outParams)}; - promise->set_value(::std::move(result)); - }, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - nullptr, context); - } - else if(ice_isOneway() || ice_isDatagram()) - { - ice_invoke_async(operation, mode, inParams, - nullptr, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - [promise](bool) - { - Result_invoke1 result; - result.ok = true; - promise->set_value(::std::move(result)); - }, - context); - } - else // Batch request - { - ice_invoke_async(operation, mode, inParams, nullptr, nullptr, nullptr, context); - Result_invoke1 result; - result.ok = true; - promise->set_value(::std::move(result)); + r = [response](Result_ice_invoke&& result) + { + response(result.ok, std::move(result.outParams)); + }; } - return promise->get_future(); + auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), r, ex, sent); + outAsync->invoke(operation, mode, ::IceInternal::makePair(inP), ctx); + return [outAsync]() { outAsync->cancel(); }; } - - ::std::function<void ()> - ice_invoke_async( - const ::std::string&, - ::Ice::OperationMode, - const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& inParams, - ::std::function<void (bool, ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>)> response, - ::std::function<void (::std::exception_ptr)> exception = nullptr, - ::std::function<void (bool)> sent = nullptr, - const ::Ice::Context& context = ::Ice::noExplicitContext); - - struct Result_invoke2 + + template<template<typename> class P = std::promise> auto + ice_invoke_async(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()) + { + return ice_invoke_async(operation, mode, ::IceInternal::makePair(inP), ctx); + } + + template<template<typename> class P = std::promise> auto + ice_invoke_async(const ::std::string& operation, + ::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()) + { + using Outgoing = ::IceInternal::InvokePromiseOutgoing<P<Result_ice_invoke>, Result_ice_invoke>; + 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; }; - - template<template<typename> class P = std::promise> - auto ice_invoke_async( - const ::std::string& operation, - ::Ice::OperationMode mode, - const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& inParams, - const ::Ice::Context& context = ::Ice::noExplicitContext) - -> decltype(std::declval<P<Result_invoke2>>().get_future()) - { - auto promise = ::std::make_shared<P<Result_invoke2>>(); - if(ice_isTwoway()) - { - ice_invoke_async(operation, mode, inParams, - [promise](bool ok, ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*> outParams) - { - Result_invoke2 result = {ok, move(outParams)}; - promise->set_value(::std::move(result)); - }, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - nullptr, context); - } - else if(ice_isOneway() || ice_isDatagram()) - { - ice_invoke_async(operation, mode, inParams, - nullptr, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - [promise](bool) - { - Result_invoke2 result; - result.ok = true; - promise->set_value(::std::move(result)); - }, - context); - } - else // Batch request + + ::std::function<void ()> + ice_invoke_async(const ::std::string& operation, + ::Ice::OperationMode mode, + const ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>& inP, + ::std::function<void (bool, ::std::pair<const ::Ice::Byte*, const ::Ice::Byte*>)> response, + ::std::function<void (::std::exception_ptr)> ex = nullptr, + ::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; + if(response) { - ice_invoke_async(operation, mode, inParams, nullptr, nullptr, nullptr, context); - Result_invoke2 result; - result.ok = true; - promise->set_value(::std::move(result)); + r = [response](Result_ice_invoke_zerocopy&& result) + { + response(result.ok, std::move(result.outParams)); + }; } - return promise->get_future(); + auto outAsync = ::std::make_shared<Outgoing>(shared_from_this(), r, ex, sent); + outAsync->invoke(operation, mode, inP, ctx); + return [outAsync]() { outAsync->cancel(); }; } ::Ice::Identity ice_getIdentity() const; @@ -426,60 +535,71 @@ public: ::std::shared_ptr<::Ice::ObjectPrx> ice_connectionId(const ::std::string&) const; ::std::string ice_getConnectionId() const; - - ::std::shared_ptr<::Ice::Connection> ice_getConnection(); + ::std::shared_ptr<::Ice::Connection> + ice_getConnection() + { + return ice_getConnection_async().get(); + } ::std::function<void ()> - ice_getConnection_async( - ::std::function<void (::std::shared_ptr<::Ice::Connection>)> response, - ::std::function<void (::std::exception_ptr)> exception = nullptr, - ::std::function<void (bool)> sent = nullptr); - + ice_getConnection_async(::std::function<void (::std::shared_ptr<::Ice::Connection>)> response, + ::std::function<void (::std::exception_ptr)> ex = nullptr, + ::std::function<void (bool)> sent = nullptr) + { + using LambdaOutgoing = ::IceInternal::ProxyGetConnectionLambda; + auto outAsync = ::std::make_shared<LambdaOutgoing>(shared_from_this(), + [this]() + { + return ice_getCachedConnection(); + }, + response, ex, sent); + __ice_getConnection(outAsync); + return [outAsync]() { outAsync->cancel(); }; + } - template<template<typename> class P = std::promise> - auto ice_getConnection_async() - -> decltype(std::declval<P<::std::shared_ptr<::Ice::Connection>>>().get_future()) + template<template<typename> class P = std::promise> auto + ice_getConnection_async() -> decltype(std::declval<P<::std::shared_ptr<::Ice::Connection>>>().get_future()) { - auto promise = ::std::make_shared<P<::std::shared_ptr<::Ice::Connection>>>(); - ice_getConnection_async( - [promise](::std::shared_ptr<::Ice::Connection> connection) - { - promise->set_value(::std::move(connection)); - }, - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }); - return promise->get_future(); + using PromiseOutgoing = ::IceInternal::ProxyGetConnectionPromise<P<::std::shared_ptr<::Ice::Connection>>>; + auto outAsync = ::std::make_shared<PromiseOutgoing>(shared_from_this(), + [this]() + { + return ice_getCachedConnection(); + }); + __ice_getConnection(outAsync); + return outAsync->getFuture(); } + void __ice_getConnection(const ::std::shared_ptr<::IceInternal::ProxyGetConnection>&); + ::std::shared_ptr<::Ice::Connection> ice_getCachedConnection() const; - void ice_flushBatchRequests(); + bool ice_flushBatchRequests() + { + return ice_flushBatchRequests_async().get(); + } std::function<void ()> - ice_flushBatchRequests_async( - ::std::function<void (::std::exception_ptr)> exception, - ::std::function<void (bool)> sent = nullptr); - + ice_flushBatchRequests_async(::std::function<void (::std::exception_ptr)> ex, + ::std::function<void (bool)> sent = nullptr) + { + using LambdaOutgoing = ::IceInternal::ProxyFlushBatchLambda; + auto outAsync = ::std::make_shared<LambdaOutgoing>(shared_from_this(), ex, sent); + __ice_flushBatchRequests(outAsync); + return [outAsync]() { outAsync->cancel(); }; + } - template<template<typename> class P = std::promise> - auto ice_flushBatchRequests_async() - -> decltype(std::declval<P<bool>>().get_future()) + template<template<typename> class P = std::promise> auto + ice_flushBatchRequests_async() -> decltype(std::declval<P<bool>>().get_future()) { - auto promise = ::std::make_shared<P<bool>>(); - ice_flushBatchRequests_async( - [promise](::std::exception_ptr ex) - { - promise->set_exception(::std::move(ex)); - }, - [promise](bool sent) - { - promise->set_value(sent); - }); - return promise->get_future(); + using PromiseOutgoing = ::IceInternal::ProxyFlushBatchPromise<P<bool>>; + auto outAsync = ::std::make_shared<PromiseOutgoing>(shared_from_this()); + __ice_flushBatchRequests(outAsync); + return outAsync->getFuture(); } + void __ice_flushBatchRequests(const ::std::shared_ptr<::IceInternal::ProxyFlushBatchAsync>&); + const ::IceInternal::ReferencePtr& __reference() const { return _reference; } void __copyFrom(const std::shared_ptr<::Ice::ObjectPrx>&); @@ -500,6 +620,41 @@ 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()) + { + auto outAsync = ::std::make_shared<::IceInternal::PromiseOutgoing<P<R>, R>>(shared_from_this(), sync); + (obj->*fn)(outAsync, std::forward<Args>(args)...); + return outAsync->getFuture(); + } + + template<typename R, 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<R>>(shared_from_this(), r, e, s); + (obj->*fn)(outAsync, std::forward<Args>(args)...); + 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>(); @@ -624,9 +779,9 @@ public: { return ::std::dynamic_pointer_cast<Prx>(ObjectPrx::ice_encodingVersion(version)); } - + protected: - + virtual ::std::shared_ptr<ObjectPrx> __newInstance() const { return IceInternal::createProxy<Prx>(); @@ -1384,9 +1539,9 @@ public: { return dynamic_cast<Prx*>(::IceProxy::Ice::Object::ice_encodingVersion(version).get()); } - + protected: - + virtual Object* __newInstance() const { return new Prx(); diff --git a/cpp/include/Ice/ProxyF.h b/cpp/include/Ice/ProxyF.h index add97950f37..c931b6c4fae 100644 --- a/cpp/include/Ice/ProxyF.h +++ b/cpp/include/Ice/ProxyF.h @@ -10,8 +10,6 @@ #ifndef ICE_PROXY_F_H #define ICE_PROXY_F_H -#include <IceUtil/Shared.h> - #include <Ice/Config.h> #include <Ice/ProxyHandle.h> @@ -29,45 +27,6 @@ inline Object* upCast(Object* o) { return o; } } -namespace IceDelegate -{ - -namespace Ice -{ - -class Object; -inline Object* upCast(Object* o) { return o; } - -} - -} - -namespace IceDelegateM -{ - -namespace Ice -{ - -class Object; -inline Object* upCast(Object* o) { return o; } - -} - -} - -namespace IceDelegateD -{ - -namespace Ice -{ - -class Object; -inline Object* upCast(Object* o) { return o; } - -} - -} - namespace Ice { @@ -75,7 +34,9 @@ typedef IceInternal::ProxyHandle< ::IceProxy::Ice::Object> ObjectPrx; typedef ObjectPrx ObjectPrxPtr; } + #else // C++11 mapping + namespace Ice { @@ -92,20 +53,6 @@ template<typename P> } -namespace IceProxy -{ - -namespace Ice -{ - -// -// ObjectPrx alias for compatibility with C++98 mapping -// -typedef ::Ice::ObjectPrx Object; - -} - -} #endif #endif diff --git a/cpp/include/Ice/StreamHelpers.h b/cpp/include/Ice/StreamHelpers.h index 10bd6e723af..f4485ce862f 100644 --- a/cpp/include/Ice/StreamHelpers.h +++ b/cpp/include/Ice/StreamHelpers.h @@ -7,14 +7,13 @@ // // ********************************************************************** -#ifndef ICE_STREAM_TRAITS_H -#define ICE_STREAM_TRAITS_H +#ifndef ICE_STREAM_HELPERS_H +#define ICE_STREAM_HELPERS_H #include <IceUtil/ScopedArray.h> #include <IceUtil/Iterator.h> #include <Ice/ObjectF.h> -#include <Ice/Traits.h> namespace Ice { @@ -93,40 +92,73 @@ struct IsMap static const bool value = IsContainer<T>::value && sizeof(test<T>(0)) == sizeof(char); }; +#ifdef ICE_CPP11_MAPPING + // // Base traits template. // Types with no specialized trait use this trait. // -template<typename T, typename Enabler = void> +template<typename T, typename Enabler = void> struct StreamableTraits { - static const StreamHelperCategory helper = IsMap<T>::value ? StreamHelperCategoryDictionary : - (IsContainer<T>::value ? StreamHelperCategorySequence : StreamHelperCategoryUnknown); + static const StreamHelperCategory helper = StreamHelperCategoryUnknown; // // When extracting a sequence<T> from a stream, we can ensure the // stream has at least StreamableTraits<T>::minWireSize * size bytes // For containers, the minWireSize is 1 (just 1 byte for an empty container). // - static const int minWireSize = 1; + //static const int minWireSize = 1; // // Is this type encoded on a fixed number of bytes? // Used only for marshaling/unmarshaling optional data members and parameters. // + //static const bool fixedLength = false; +}; + +template<typename T> +struct StreamableTraits<T, typename ::std::enable_if<IsMap<T>::value || IsContainer<T>::value>::type> +{ + static const StreamHelperCategory helper = IsMap<T>::value ? StreamHelperCategoryDictionary : StreamHelperCategorySequence; + static const int minWireSize = 1; static const bool fixedLength = false; }; +template<typename T> +struct StreamableTraits<T, typename ::std::enable_if<::std::is_base_of<::Ice::UserException, T>::value>::type> +{ + static const StreamHelperCategory helper = StreamHelperCategoryUserException; + + // + // There is no sequence/dictionary of UserException (so no need for minWireSize) + // and no optional UserException (so no need for fixedLength) + // +}; + +#else + // -// StreamableTraits specialization for array / range mapped sequences -// The type can be a std::pair<T, T> or a -// std::pair<IceUtil::ScopedArray<T>, std::pair<const T*, const T*> > +// Base traits template. +// Types with no specialized trait use this trait. // -template<typename T, typename U> -struct StreamableTraits< ::std::pair<T, U> > +template<typename T, typename Enabler = void> +struct StreamableTraits { - static const StreamHelperCategory helper = StreamHelperCategorySequence; + static const StreamHelperCategory helper = IsMap<T>::value ? StreamHelperCategoryDictionary : + (IsContainer<T>::value ? StreamHelperCategorySequence : StreamHelperCategoryUnknown); + + // + // When extracting a sequence<T> from a stream, we can ensure the + // stream has at least StreamableTraits<T>::minWireSize * size bytes + // For containers, the minWireSize is 1 (just 1 byte for an empty container). + // static const int minWireSize = 1; + + // + // Is this type encoded on a fixed number of bytes? + // Used only for marshaling/unmarshaling optional data members and parameters. + // static const bool fixedLength = false; }; @@ -143,7 +175,20 @@ struct StreamableTraits<UserException> // and no optional UserException (so no need for fixedLength) // }; +#endif +// +// StreamableTraits specialization for array / range mapped sequences +// The type can be a std::pair<T, T> or a +// std::pair<IceUtil::ScopedArray<T>, std::pair<const T*, const T*> > +// +template<typename T, typename U> +struct StreamableTraits< ::std::pair<T, U> > +{ + static const StreamHelperCategory helper = StreamHelperCategorySequence; + static const int minWireSize = 1; + static const bool fixedLength = false; +}; // // StreamableTraits specialization for builtins (these are needed for sequence @@ -236,7 +281,7 @@ struct StreamableTraits< ::std::vector<bool> > #ifdef ICE_CPP11_MAPPING template<typename T> -struct StreamableTraits<::std::shared_ptr<T>, typename ::std::enable_if<IsProxy<T>::value>::type> +struct StreamableTraits<::std::shared_ptr<T>, typename ::std::enable_if<::std::is_base_of<::Ice::ObjectPrx, T>::value>::type> { static const StreamHelperCategory helper = StreamHelperCategoryProxy; static const int minWireSize = 2; @@ -254,7 +299,7 @@ struct StreamableTraits< ::IceInternal::ProxyHandle<T> > #ifdef ICE_CPP11_MAPPING template<typename T> -struct StreamableTraits<::std::shared_ptr<T>, typename ::std::enable_if<IsValue<T>::value>::type> +struct StreamableTraits<::std::shared_ptr<T>, typename ::std::enable_if<::std::is_base_of<::Ice::Value, T>::value>::type> { static const StreamHelperCategory helper = StreamHelperCategoryClass; static const int minWireSize = 1; @@ -323,7 +368,6 @@ struct StreamHelper<T, StreamHelperCategoryStruct> } }; - // Helper for class structs template<typename T> struct StreamHelper<T, StreamHelperCategoryStructClass> diff --git a/cpp/include/Ice/Traits.h b/cpp/include/Ice/Traits.h deleted file mode 100644 index f1e2cb50401..00000000000 --- a/cpp/include/Ice/Traits.h +++ /dev/null @@ -1,21 +0,0 @@ - -#ifndef ICE_TRAITS_H -#define ICE_TRAITS_H - -#ifdef ICE_CPP11_MAPPING - -#include <type_traits> - -namespace Ice -{ - -class ObjectPrx; -class Value; - -template<class T> using IsProxy = ::std::is_base_of<::Ice::ObjectPrx, T>; -template<class T> using IsValue = ::std::is_base_of<::Ice::Value, T>; - -} -#endif - -#endif diff --git a/cpp/include/Ice/VirtualShared.h b/cpp/include/Ice/VirtualShared.h index 3dd06ea55e0..62ad8f6771c 100644 --- a/cpp/include/Ice/VirtualShared.h +++ b/cpp/include/Ice/VirtualShared.h @@ -20,24 +20,24 @@ namespace Ice class VirtualEnableSharedFromThisBase : public std::enable_shared_from_this<VirtualEnableSharedFromThisBase> { public: + virtual ~VirtualEnableSharedFromThisBase() = default; }; template<typename T> class EnableSharedFromThis : public virtual VirtualEnableSharedFromThisBase { - public: std::shared_ptr<T> shared_from_this() const { return std::dynamic_pointer_cast<T>( - std::const_pointer_cast<VirtualEnableSharedFromThisBase>(VirtualEnableSharedFromThisBase::shared_from_this())); + std::const_pointer_cast<VirtualEnableSharedFromThisBase>( + VirtualEnableSharedFromThisBase::shared_from_this())); } - + std::weak_ptr<T> weak_from_this() const { - std::weak_ptr<T> self = shared_from_this(); - return self; + return shared_from_this(); } }; |