Switch to fully supported C++17

This commit is contained in:
sangelovic
2020-02-01 22:58:34 +01:00
committed by Stanislav Angelovič
parent d591b69f92
commit 975f1bf07f
19 changed files with 129 additions and 192 deletions
+4 -13
View File
@@ -46,9 +46,6 @@ namespace sdbus {
namespace sdbus {
template <typename... _Args>
inline constexpr bool are_strings_v = std::conjunction<std::is_convertible<_Args, std::string>...>::value;
class MethodRegistrator
{
public:
@@ -57,16 +54,11 @@ namespace sdbus {
~MethodRegistrator() noexcept(false);
MethodRegistrator& onInterface(std::string interfaceName);
template <typename _Function>
std::enable_if_t<!is_async_method_v<_Function>, MethodRegistrator&> implementedAs(_Function&& callback);
template <typename _Function>
std::enable_if_t<is_async_method_v<_Function>, MethodRegistrator&> implementedAs(_Function&& callback);
template <typename _Function> MethodRegistrator& implementedAs(_Function&& callback);
MethodRegistrator& withInputParamNames(std::vector<std::string> paramNames);
template <typename... _String>
std::enable_if_t<are_strings_v<_String...>, MethodRegistrator&> withInputParamNames(_String... paramNames);
template <typename... _String> MethodRegistrator& withInputParamNames(_String... paramNames);
MethodRegistrator& withOutputParamNames(std::vector<std::string> paramNames);
template <typename... _String>
std::enable_if_t<are_strings_v<_String...>, MethodRegistrator&> withOutputParamNames(_String... paramNames);
template <typename... _String> MethodRegistrator& withOutputParamNames(_String... paramNames);
MethodRegistrator& markAsDeprecated();
MethodRegistrator& markAsPrivileged();
MethodRegistrator& withNoReply();
@@ -94,8 +86,7 @@ namespace sdbus {
SignalRegistrator& onInterface(std::string interfaceName);
template <typename... _Args> SignalRegistrator& withParameters();
template <typename... _Args> SignalRegistrator& withParameters(std::vector<std::string> paramNames);
template <typename... _Args, typename... _String>
std::enable_if_t<are_strings_v<_String...>, SignalRegistrator&> withParameters(_String... paramNames);
template <typename... _Args, typename... _String> SignalRegistrator& withParameters(_String... paramNames);
SignalRegistrator& markAsDeprecated();
private:
+27 -40
View File
@@ -88,38 +88,7 @@ namespace sdbus {
}
template <typename _Function>
inline std::enable_if_t<!is_async_method_v<_Function>, MethodRegistrator&>
MethodRegistrator::implementedAs(_Function&& callback)
{
inputSignature_ = signature_of_function_input_arguments<_Function>::str();
outputSignature_ = signature_of_function_output_arguments<_Function>::str();
methodCallback_ = [callback = std::forward<_Function>(callback)](MethodCall call)
{
// Create a tuple of callback input arguments' types, which will be used
// as a storage for the argument values deserialized from the message.
tuple_of_function_input_arg_types_t<_Function> inputArgs;
// Deserialize input arguments from the message into the tuple
call >> inputArgs;
// Invoke callback with input arguments from the tuple.
// For callbacks returning a non-void value, `apply' also returns that value.
// For callbacks returning void, `apply' returns an empty tuple.
auto ret = sdbus::apply(callback, inputArgs); // We don't yet have C++17's std::apply :-(
// The return value is stored to the reply message.
// In case of void functions, ret is an empty tuple and thus nothing is stored.
auto reply = call.createReply();
reply << ret;
reply.send();
};
return *this;
}
template <typename _Function>
inline std::enable_if_t<is_async_method_v<_Function>, MethodRegistrator&>
MethodRegistrator::implementedAs(_Function&& callback)
MethodRegistrator& MethodRegistrator::implementedAs(_Function&& callback)
{
inputSignature_ = signature_of_function_input_arguments<_Function>::str();
outputSignature_ = signature_of_function_output_arguments<_Function>::str();
@@ -132,8 +101,22 @@ namespace sdbus {
// Deserialize input arguments from the message into the tuple.
call >> inputArgs;
// Invoke callback with input arguments from the tuple.
sdbus::apply(callback, typename function_traits<_Function>::async_result_t{std::move(call)}, std::move(inputArgs));
if constexpr (!is_async_method_v<_Function>)
{
// Invoke callback with input arguments from the tuple.
auto ret = sdbus::apply(callback, inputArgs);
// Store output arguments to the reply message and send it back.
auto reply = call.createReply();
reply << ret;
reply.send();
}
else
{
// Invoke callback with input arguments from the tuple and with result object to be set later
using AsyncResult = typename function_traits<_Function>::async_result_t;
sdbus::apply(callback, AsyncResult{std::move(call)}, std::move(inputArgs));
}
};
return *this;
@@ -147,8 +130,10 @@ namespace sdbus {
}
template <typename... _String>
inline std::enable_if_t<are_strings_v<_String...>, MethodRegistrator&> MethodRegistrator::withInputParamNames(_String... paramNames)
inline MethodRegistrator& MethodRegistrator::withInputParamNames(_String... paramNames)
{
static_assert(std::conjunction_v<std::is_convertible<_String, std::string>...>, "Parameter names must be (convertible to) strings");
return withInputParamNames({paramNames...});
}
@@ -160,8 +145,10 @@ namespace sdbus {
}
template <typename... _String>
inline std::enable_if_t<are_strings_v<_String...>, MethodRegistrator&> MethodRegistrator::withOutputParamNames(_String... paramNames)
inline MethodRegistrator& MethodRegistrator::withOutputParamNames(_String... paramNames)
{
static_assert(std::conjunction_v<std::is_convertible<_String, std::string>...>, "Parameter names must be (convertible to) strings");
return withOutputParamNames({paramNames...});
}
@@ -245,9 +232,9 @@ namespace sdbus {
}
template <typename... _Args, typename... _String>
inline std::enable_if_t<are_strings_v<_String...>, SignalRegistrator&>
SignalRegistrator::withParameters(_String... paramNames)
inline SignalRegistrator& SignalRegistrator::withParameters(_String... paramNames)
{
static_assert(std::conjunction_v<std::is_convertible<_String, std::string>...>, "Parameter names must be (convertible to) strings");
static_assert(sizeof...(_Args) == sizeof...(_String), "Numbers of signal parameters and their names don't match");
return withParameters<_Args...>({paramNames...});
@@ -604,7 +591,7 @@ namespace sdbus {
reply >> args;
// Invoke callback with input arguments from the tuple.
sdbus::apply(callback, error, args); // TODO: Use std::apply when switching to full C++17 support
sdbus::apply(callback, error, args);
};
proxy_.callMethod(method_, std::move(asyncReplyHandler), timeout_);
@@ -644,7 +631,7 @@ namespace sdbus {
signal >> signalArgs;
// Invoke callback with input arguments from the tuple.
sdbus::apply(callback, signalArgs); // We don't yet have C++17's std::apply :-(
sdbus::apply(callback, signalArgs);
});
}
+7 -7
View File
@@ -200,7 +200,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
std::unique_ptr<sdbus::IConnection> createConnection();
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createConnection();
/*!
* @brief Creates/opens D-Bus system connection with a name
@@ -210,7 +210,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
std::unique_ptr<sdbus::IConnection> createConnection(const std::string& name);
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createConnection(const std::string& name);
/*!
* @brief Creates/opens D-Bus system connection
@@ -219,7 +219,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
std::unique_ptr<sdbus::IConnection> createSystemBusConnection();
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSystemBusConnection();
/*!
* @brief Creates/opens D-Bus system connection with a name
@@ -229,7 +229,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string& name);
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSystemBusConnection(const std::string& name);
/*!
* @brief Creates/opens D-Bus session connection
@@ -238,7 +238,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
std::unique_ptr<sdbus::IConnection> createSessionBusConnection();
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSessionBusConnection();
/*!
* @brief Creates/opens D-Bus session connection with a name
@@ -248,7 +248,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string& name);
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createSessionBusConnection(const std::string& name);
/*!
* @brief Creates/opens D-Bus system connection on a remote host using ssh
@@ -258,7 +258,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
std::unique_ptr<sdbus::IConnection> createRemoteSystemBusConnection(const std::string& host);
[[nodiscard]] std::unique_ptr<sdbus::IConnection> createRemoteSystemBusConnection(const std::string& host);
}
#endif /* SDBUS_CXX_ICONNECTION_H_ */
+6 -6
View File
@@ -358,7 +358,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
MethodRegistrator registerMethod(const std::string& methodName);
[[nodiscard]] MethodRegistrator registerMethod(const std::string& methodName);
/*!
* @brief Registers signal that the object will provide on D-Bus
@@ -377,7 +377,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
SignalRegistrator registerSignal(const std::string& signalName);
[[nodiscard]] SignalRegistrator registerSignal(const std::string& signalName);
/*!
* @brief Registers property that the object will provide on D-Bus
@@ -396,7 +396,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
PropertyRegistrator registerProperty(const std::string& propertyName);
[[nodiscard]] PropertyRegistrator registerProperty(const std::string& propertyName);
/*!
* @brief Sets flags (annotations) for a given interface
@@ -413,7 +413,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
InterfaceFlagsSetter setInterfaceFlags(const std::string& interfaceName);
[[nodiscard]] InterfaceFlagsSetter setInterfaceFlags(const std::string& interfaceName);
/*!
* @brief Emits signal on D-Bus
@@ -434,7 +434,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
SignalEmitter emitSignal(const std::string& signalName);
[[nodiscard]] SignalEmitter emitSignal(const std::string& signalName);
};
// Out-of-line member definitions
@@ -482,7 +482,7 @@ namespace sdbus {
* auto proxy = sdbus::createObject(connection, "/com/kistler/foo");
* @endcode
*/
std::unique_ptr<sdbus::IObject> createObject(sdbus::IConnection& connection, std::string objectPath);
[[nodiscard]] std::unique_ptr<sdbus::IObject> createObject(sdbus::IConnection& connection, std::string objectPath);
}
+13 -13
View File
@@ -178,7 +178,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
MethodInvoker callMethod(const std::string& methodName);
[[nodiscard]] MethodInvoker callMethod(const std::string& methodName);
/*!
* @brief Calls method on the proxied D-Bus object asynchronously
@@ -202,7 +202,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
AsyncMethodInvoker callMethodAsync(const std::string& methodName);
[[nodiscard]] AsyncMethodInvoker callMethodAsync(const std::string& methodName);
/*!
* @brief Registers signal handler for a given signal of the proxied D-Bus object
@@ -222,7 +222,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
SignalSubscriber uponSignal(const std::string& signalName);
[[nodiscard]] SignalSubscriber uponSignal(const std::string& signalName);
/*!
* @brief Gets value of a property of the proxied D-Bus object
@@ -241,7 +241,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
PropertyGetter getProperty(const std::string& propertyName);
[[nodiscard]] PropertyGetter getProperty(const std::string& propertyName);
/*!
* @brief Sets value of a property of the proxied D-Bus object
@@ -260,7 +260,7 @@ namespace sdbus {
*
* @throws sdbus::Error in case of failure
*/
PropertySetter setProperty(const std::string& propertyName);
[[nodiscard]] PropertySetter setProperty(const std::string& propertyName);
};
// Out-of-line member definitions
@@ -323,9 +323,9 @@ namespace sdbus {
* auto proxy = sdbus::createProxy(connection, "com.kistler.foo", "/com/kistler/foo");
* @endcode
*/
std::unique_ptr<sdbus::IProxy> createProxy( sdbus::IConnection& connection
, std::string destination
, std::string objectPath );
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( sdbus::IConnection& connection
, std::string destination
, std::string objectPath );
/*!
* @brief Creates a proxy object for a specific remote D-Bus object
@@ -346,9 +346,9 @@ namespace sdbus {
* auto proxy = sdbus::createProxy(std::move(connection), "com.kistler.foo", "/com/kistler/foo");
* @endcode
*/
std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<sdbus::IConnection>&& connection
, std::string destination
, std::string objectPath );
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( std::unique_ptr<sdbus::IConnection>&& connection
, std::string destination
, std::string objectPath );
/*!
* @brief Creates a proxy object for a specific remote D-Bus object
@@ -367,8 +367,8 @@ namespace sdbus {
* auto proxy = sdbus::createProxy("com.kistler.foo", "/com/kistler/foo");
* @endcode
*/
std::unique_ptr<sdbus::IProxy> createProxy( std::string destination
, std::string objectPath );
[[nodiscard]] std::unique_ptr<sdbus::IProxy> createProxy( std::string destination
, std::string objectPath );
}
+2 -16
View File
@@ -55,11 +55,7 @@ namespace sdbus {
// Assume the caller has already obtained message ownership
struct adopt_message_t { explicit adopt_message_t() = default; };
#ifdef __cpp_inline_variables
inline constexpr adopt_message_t adopt_message{};
#else
constexpr adopt_message_t adopt_message{};
#endif
/********************************************//**
* @class Message
@@ -166,11 +162,7 @@ namespace sdbus {
};
struct dont_request_slot_t { explicit dont_request_slot_t() = default; };
#ifdef __cpp_inline_variables
inline constexpr dont_request_slot_t dont_request_slot{};
#else
constexpr dont_request_slot_t dont_request_slot{};
#endif
class MethodCall : public Message
{
@@ -283,10 +275,7 @@ namespace sdbus {
template <typename... _Args>
void serialize_pack(Message& msg, _Args&&... args)
{
// Use initializer_list because it guarantees left to right order, and can be empty
using _ = std::initializer_list<int>;
// We are not interested in the list itself, but in the side effects
(void)_{(void(msg << std::forward<_Args>(args)), 0)...};
(msg << ... << args);
}
template <class _Tuple, std::size_t... _Is>
@@ -378,10 +367,7 @@ namespace sdbus {
template <typename... _Args>
void deserialize_pack(Message& msg, _Args&... args)
{
// Use initializer_list because it guarantees left to right order, and can be empty
using _ = std::initializer_list<int>;
// We are not interested in the list itself, but in the side effects
(void)_{(void(msg >> args), 0)...};
(msg >> ... >> args);
}
template <class _Tuple, std::size_t... _Is>
-5
View File
@@ -76,12 +76,7 @@ namespace sdbus {
{
assert(call_.isValid());
auto reply = call_.createReply();
#ifdef __cpp_fold_expressions
(reply << ... << results);
#else
using _ = std::initializer_list<int>;
(void)_{(void(reply << results), 0)...};
#endif
reply.send();
}
+9 -24
View File
@@ -245,11 +245,9 @@ namespace sdbus {
static const std::string str()
{
std::initializer_list<std::string> signatures{signature_of<_ValueTypes>::str()...};
std::string signature;
signature += "(";
for (const auto& item : signatures)
signature += item;
(signature += ... += signature_of<_ValueTypes>::str());
signature += ")";
return signature;
}
@@ -489,11 +487,8 @@ namespace sdbus {
{
static const std::string str()
{
// TODO: This could be a fold expression in C++17...
std::initializer_list<std::string> signatures{signature_of<std::decay_t<_Types>>::str()...};
std::string signature;
for (const auto& item : signatures)
signature += item;
(signature += ... += signature_of<std::decay_t<_Types>>::str());
return signature;
}
};
@@ -536,27 +531,17 @@ namespace sdbus {
return std::forward<_Function>(f)(e, std::get<_I>(std::forward<_Tuple>(t))...);
}
// Version of apply_impl for functions returning non-void values.
// In this case just forward function return value.
// For non-void returning functions, apply_impl simply returns function return value (a tuple of values).
// For void-returning functions, apply_impl returns an empty tuple.
template <class _Function, class _Tuple, std::size_t... _I>
constexpr decltype(auto) apply_impl( _Function&& f
, _Tuple&& t
, std::index_sequence<_I...>
, std::enable_if_t<!std::is_void<function_result_t<_Function>>::value>* = nullptr)
, std::index_sequence<_I...> )
{
return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...);
}
// Version of apply_impl for functions returning void.
// In this case, to have uniform code on the caller side, return empty tuple, our synonym for `void'.
template <class _Function, class _Tuple, std::size_t... _I>
constexpr decltype(auto) apply_impl( _Function&& f
, _Tuple&& t
, std::index_sequence<_I...>
, std::enable_if_t<std::is_void<function_result_t<_Function>>::value>* = nullptr)
{
std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...);
return std::tuple<>{};
if constexpr (!std::is_void_v<function_result_t<_Function>>)
return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...);
else
return std::forward<_Function>(f)(std::get<_I>(std::forward<_Tuple>(t))...), std::tuple<>{};
}
}
-4
View File
@@ -178,11 +178,7 @@ namespace sdbus {
};
struct adopt_fd_t { explicit adopt_fd_t() = default; };
#ifdef __cpp_inline_variables
inline constexpr adopt_fd_t adopt_fd{};
#else
constexpr adopt_fd_t adopt_fd{};
#endif
/********************************************//**
* @struct UnixFd