Move C++17 uncaught_exceptions to public API

This commit is contained in:
sangelovic
2019-11-10 17:31:58 +01:00
parent 3a76e9c120
commit d50a15b2a2
6 changed files with 48 additions and 278 deletions

View File

@@ -53,7 +53,7 @@ namespace sdbus {
MethodRegistrator& operator=(MethodRegistrator&& other) = default;
~MethodRegistrator() noexcept(false);
MethodRegistrator& onInterface(const std::string& interfaceName);
MethodRegistrator& onInterface(std::string interfaceName);
template <typename _Function>
std::enable_if_t<!is_async_method_v<_Function>, MethodRegistrator&> implementedAs(_Function&& callback);
template <typename _Function>
@@ -102,7 +102,7 @@ namespace sdbus {
PropertyRegistrator& operator=(PropertyRegistrator&& other) = default;
~PropertyRegistrator() noexcept(false);
PropertyRegistrator& onInterface(const std::string& interfaceName);
PropertyRegistrator& onInterface(std::string interfaceName);
template <typename _Function> PropertyRegistrator& withGetter(_Function&& callback);
template <typename _Function> PropertyRegistrator& withSetter(_Function&& callback);
PropertyRegistrator& markAsDeprecated();
@@ -205,12 +205,12 @@ namespace sdbus {
{
public:
SignalSubscriber(IProxy& proxy, const std::string& signalName);
SignalSubscriber& onInterface(const std::string& interfaceName);
SignalSubscriber& onInterface(std::string interfaceName);
template <typename _Function> void call(_Function&& callback);
private:
IProxy& proxy_;
std::string signalName_;
const std::string& signalName_;
std::string interfaceName_;
};
@@ -222,14 +222,14 @@ namespace sdbus {
private:
IProxy& proxy_;
std::string propertyName_;
const std::string& propertyName_;
};
class PropertySetter
{
public:
PropertySetter(IProxy& proxy, const std::string& propertyName);
PropertySetter& onInterface(const std::string& interfaceName);
PropertySetter& onInterface(std::string interfaceName);
template <typename _Value> void toValue(const _Value& value);
void toValue(const sdbus::Variant& value);

View File

@@ -36,7 +36,8 @@
#include <sdbus-c++/Error.h>
#include <string>
#include <tuple>
/*#include <exception>*/
#include <exception>
#include <cassert>
namespace sdbus {
@@ -44,12 +45,10 @@ namespace sdbus {
/*** MethodRegistrator ***/
/*** ----------------- ***/
// Moved into the library to isolate from C++17 dependency
/*
inline MethodRegistrator::MethodRegistrator(IObject& object, const std::string& methodName)
: object_(object)
, methodName_(methodName)
, exceptions_(std::uncaught_exceptions()) // Needs C++17
, exceptions_(std::uncaught_exceptions())
{
}
@@ -59,8 +58,8 @@ namespace sdbus {
if (std::uncaught_exceptions() != exceptions_)
return;
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when registering a DBus method", EINVAL);
SDBUS_THROW_ERROR_IF(!methodCallback_, "Method handler not specified when registering a DBus method", EINVAL);
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
assert(methodCallback_); // implementedAs() must be placed/called prior to this function
// registerMethod() can throw. But as the MethodRegistrator shall always be used as an unnamed,
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
@@ -73,11 +72,10 @@ namespace sdbus {
// to the exception thrown from here if the caller is a destructor itself.
object_.registerMethod(interfaceName_, methodName_, inputSignature_, outputSignature_, std::move(methodCallback_), flags_);
}
*/
inline MethodRegistrator& MethodRegistrator::onInterface(const std::string& interfaceName)
inline MethodRegistrator& MethodRegistrator::onInterface(std::string interfaceName)
{
interfaceName_ = interfaceName;
interfaceName_ = std::move(interfaceName);
return *this;
}
@@ -157,11 +155,9 @@ namespace sdbus {
/*** SignalRegistrator ***/
/*** ----------------- ***/
// Moved into the library to isolate from C++17 dependency
/*
inline SignalRegistrator::SignalRegistrator(IObject& object, std::string signalName)
inline SignalRegistrator::SignalRegistrator(IObject& object, const std::string& signalName)
: object_(object)
, signalName_(std::move(signalName))
, signalName_(signalName)
, exceptions_(std::uncaught_exceptions())
{
}
@@ -172,8 +168,7 @@ namespace sdbus {
if (std::uncaught_exceptions() != exceptions_)
return;
if (interfaceName_.empty())
throw sdbus::Exception("DBus interface not specified when registering a DBus signal");
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
// registerSignal() can throw. But as the SignalRegistrator shall always be used as an unnamed,
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
@@ -184,9 +179,8 @@ namespace sdbus {
// Therefore, we can allow registerSignal() to throw even if we are in the destructor.
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
// to the exception thrown from here if the caller is a destructor itself.
object_.registerSignal(interfaceName_, signalName_, signalSignature_);
object_.registerSignal(interfaceName_, signalName_, signalSignature_, flags_);
}
*/
inline SignalRegistrator& SignalRegistrator::onInterface(std::string interfaceName)
{
@@ -214,11 +208,9 @@ namespace sdbus {
/*** PropertyRegistrator ***/
/*** ------------------- ***/
// Moved into the library to isolate from C++17 dependency
/*
inline PropertyRegistrator::PropertyRegistrator(IObject& object, std::string propertyName)
inline PropertyRegistrator::PropertyRegistrator(IObject& object, const std::string& propertyName)
: object_(object)
, propertyName_(std::move(propertyName))
, propertyName_(propertyName)
, exceptions_(std::uncaught_exceptions())
{
}
@@ -229,7 +221,7 @@ namespace sdbus {
if (std::uncaught_exceptions() != exceptions_)
return;
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when registering a DBus property", EINVAL);
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
// registerProperty() can throw. But as the PropertyRegistrator shall always be used as an unnamed,
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
@@ -240,17 +232,17 @@ namespace sdbus {
// Therefore, we can allow registerProperty() to throw even if we are in the destructor.
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
// to the exception thrown from here if the caller is a destructor itself.
object_.registerProperty( std::move(interfaceName_)
, std::move(propertyName_)
, std::move(propertySignature_)
object_.registerProperty( interfaceName_
, propertyName_
, propertySignature_
, std::move(getter_)
, std::move(setter_) );
, std::move(setter_)
, flags_ );
}
*/
inline PropertyRegistrator& PropertyRegistrator::onInterface(const std::string& interfaceName)
inline PropertyRegistrator& PropertyRegistrator::onInterface(std::string interfaceName)
{
interfaceName_ = interfaceName;
interfaceName_ = std::move(interfaceName);
return *this;
}
@@ -323,8 +315,6 @@ namespace sdbus {
/*** InterfaceFlagsSetter ***/
/*** -------------------- ***/
// Moved into the library to isolate from C++17 dependency
/*
inline InterfaceFlagsSetter::InterfaceFlagsSetter(IObject& object, const std::string& interfaceName)
: object_(object)
, interfaceName_(interfaceName)
@@ -338,8 +328,6 @@ namespace sdbus {
if (std::uncaught_exceptions() != exceptions_)
return;
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when setting its flags", EINVAL);
// setInterfaceFlags() can throw. But as the InterfaceFlagsSetter shall always be used as an unnamed,
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
// shall never happen. I.e. it should not happen that this destructor is directly called
@@ -349,10 +337,8 @@ namespace sdbus {
// Therefore, we can allow setInterfaceFlags() to throw even if we are in the destructor.
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
// to the exception thrown from here if the caller is a destructor itself.
object_.setInterfaceFlags( std::move(interfaceName_)
, std::move(flags_) );
object_.setInterfaceFlags(interfaceName_, std::move(flags_));
}
*/
inline InterfaceFlagsSetter& InterfaceFlagsSetter::markAsDeprecated()
{
@@ -386,8 +372,6 @@ namespace sdbus {
/*** SignalEmitter ***/
/*** ------------- ***/
// Moved into the library to isolate from C++17 dependency
/*
inline SignalEmitter::SignalEmitter(IObject& object, const std::string& signalName)
: object_(object)
, signalName_(signalName)
@@ -401,9 +385,6 @@ namespace sdbus {
if (std::uncaught_exceptions() != exceptions_)
return;
if (!signal_.isValid())
throw sdbus::Exception("DBus interface not specified when emitting a DBus signal");
// emitSignal() can throw. But as the SignalEmitter shall always be used as an unnamed,
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
// shall never happen. I.e. it should not happen that this destructor is directly called
@@ -415,7 +396,6 @@ namespace sdbus {
// to the exception thrown from here if the caller is a destructor itself.
object_.emitSignal(signal_);
}
*/
inline SignalEmitter& SignalEmitter::onInterface(const std::string& interfaceName)
{
@@ -427,7 +407,7 @@ namespace sdbus {
template <typename... _Args>
inline void SignalEmitter::withArguments(_Args&&... args)
{
SDBUS_THROW_ERROR_IF(!signal_.isValid(), "DBus interface not specified when emitting a DBus signal", EINVAL);
assert(signal_.isValid()); // onInterface() must be placed/called prior to withArguments()
detail::serialize_pack(signal_, std::forward<_Args>(args)...);
}
@@ -436,9 +416,7 @@ namespace sdbus {
/*** MethodInvoker ***/
/*** ------------- ***/
// Moved into the library to isolate from C++17 dependency
/*
inline MethodInvoker::MethodInvoker(IProxy& proxyObject, const std::string& methodName)
inline MethodInvoker::MethodInvoker(IProxy& proxy, const std::string& methodName)
: proxy_(proxy)
, methodName_(methodName)
, exceptions_(std::uncaught_exceptions())
@@ -452,9 +430,6 @@ namespace sdbus {
if (methodCalled_ || std::uncaught_exceptions() != exceptions_)
return;
if (!method_.isValid())
throw sdbus::Exception("DBus interface not specified when calling a DBus method");
// callMethod() can throw. But as the MethodInvoker shall always be used as an unnamed,
// temporary object, i.e. not as a stack-allocated object, the double-exception situation
// shall never happen. I.e. it should not happen that this destructor is directly called
@@ -464,9 +439,8 @@ namespace sdbus {
// Therefore, we can allow callMethod() to throw even if we are in the destructor.
// Bottomline is, to be on the safe side, the caller must take care of catching and reacting
// to the exception thrown from here if the caller is a destructor itself.
proxy_.callMethod(method_);
proxy_.callMethod(method_, timeout_);
}
*/
inline MethodInvoker& MethodInvoker::onInterface(const std::string& interfaceName)
{
@@ -492,7 +466,7 @@ namespace sdbus {
template <typename... _Args>
inline MethodInvoker& MethodInvoker::withArguments(_Args&&... args)
{
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
detail::serialize_pack(method_, std::forward<_Args>(args)...);
@@ -502,7 +476,7 @@ namespace sdbus {
template <typename... _Args>
inline void MethodInvoker::storeResultsTo(_Args&... args)
{
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
auto reply = proxy_.callMethod(method_, timeout_);
methodCalled_ = true;
@@ -512,7 +486,7 @@ namespace sdbus {
inline void MethodInvoker::dontExpectReply()
{
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
method_.dontExpectReply();
}
@@ -551,7 +525,7 @@ namespace sdbus {
template <typename... _Args>
inline AsyncMethodInvoker& AsyncMethodInvoker::withArguments(_Args&&... args)
{
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
detail::serialize_pack(method_, std::forward<_Args>(args)...);
@@ -561,7 +535,7 @@ namespace sdbus {
template <typename _Function>
void AsyncMethodInvoker::uponReplyInvoke(_Function&& callback)
{
SDBUS_THROW_ERROR_IF(!method_.isValid(), "DBus interface not specified when calling a DBus method", EINVAL);
assert(method_.isValid()); // onInterface() must be placed/called prior to this function
auto asyncReplyHandler = [callback = std::forward<_Function>(callback)](MethodReply& reply, const Error* error)
{
@@ -590,9 +564,9 @@ namespace sdbus {
{
}
inline SignalSubscriber& SignalSubscriber::onInterface(const std::string& interfaceName)
inline SignalSubscriber& SignalSubscriber::onInterface(std::string interfaceName)
{
interfaceName_ = interfaceName;
interfaceName_ = std::move(interfaceName);
return *this;
}
@@ -600,7 +574,7 @@ namespace sdbus {
template <typename _Function>
inline void SignalSubscriber::call(_Function&& callback)
{
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when subscribing to a signal", EINVAL);
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
proxy_.registerSignalHandler( interfaceName_
, signalName_
@@ -649,9 +623,9 @@ namespace sdbus {
{
}
inline PropertySetter& PropertySetter::onInterface(const std::string& interfaceName)
inline PropertySetter& PropertySetter::onInterface(std::string interfaceName)
{
interfaceName_ = interfaceName;
interfaceName_ = std::move(interfaceName);
return *this;
}
@@ -664,7 +638,7 @@ namespace sdbus {
inline void PropertySetter::toValue(const sdbus::Variant& value)
{
SDBUS_THROW_ERROR_IF(interfaceName_.empty(), "DBus interface not specified when setting a property", EINVAL);
assert(!interfaceName_.empty()); // onInterface() must be placed/called prior to this function
proxy_
.callMethod("Set")