diff --git a/include/sdbus-c++/Message.h b/include/sdbus-c++/Message.h index 9c85c01..e17892a 100644 --- a/include/sdbus-c++/Message.h +++ b/include/sdbus-c++/Message.h @@ -29,9 +29,10 @@ #include #include -#include -#include #include +#include +#include +#include #if __cplusplus >= 202002L #include #endif @@ -100,6 +101,8 @@ namespace sdbus { template Message& operator<<(const std::span<_Element, _Extent>& items); #endif + template >> + Message& operator<<(const _Enum& item); template Message& operator<<(const std::map<_Key, _Value, _Compare, _Allocator>& items); template @@ -132,6 +135,8 @@ namespace sdbus { template Message& operator>>(std::span<_Element, _Extent>& items); #endif + template >> + Message& operator>>(_Enum& item); template Message& operator>>(std::map<_Key, _Value, _Compare, _Allocator>& items); template @@ -332,6 +337,12 @@ namespace sdbus { } #endif + template + inline Message& Message::operator<<(const _Enum &item) + { + return operator<<(static_cast>(item)); + } + template inline void Message::serializeArray(const _Array& items) { @@ -457,6 +468,15 @@ namespace sdbus { } #endif + template + inline Message& Message::operator>>(_Enum& item) + { + std::underlying_type_t<_Enum> val; + *this >> val; + item = static_cast<_Enum>(val); + return *this; + } + template inline void Message::deserializeArray(_Array& items) { diff --git a/include/sdbus-c++/TypeTraits.h b/include/sdbus-c++/TypeTraits.h index 1de2ef4..5112d61 100644 --- a/include/sdbus-c++/TypeTraits.h +++ b/include/sdbus-c++/TypeTraits.h @@ -98,7 +98,7 @@ namespace sdbus { inline constexpr dont_expect_reply_t dont_expect_reply{}; // Template specializations for getting D-Bus signatures from C++ types - template + template struct signature_of { static constexpr bool is_valid = false; @@ -120,7 +120,7 @@ namespace sdbus { template struct signature_of<_T&> - : public signature_of<_T> + : public signature_of<_T> {}; template <> @@ -405,6 +405,12 @@ namespace sdbus { }; #endif + template + struct signature_of<_Enum, typename std::enable_if_t>> + : public signature_of> + {}; + + template struct signature_of> { @@ -429,7 +435,6 @@ namespace sdbus { } }; - // Function traits implementation inspired by (c) kennytm, // https://github.com/kennytm/utils/blob/master/traits.hpp template diff --git a/tests/unittests/Message_test.cpp b/tests/unittests/Message_test.cpp index eb17152..ede790d 100644 --- a/tests/unittests/Message_test.cpp +++ b/tests/unittests/Message_test.cpp @@ -347,6 +347,24 @@ TEST(AMessage, CanCarryDBusArrayOfNontrivialTypesGivenAsStdSpan) } #endif +TEST(AMessage, CanCarryAnEnumValue) +{ + auto msg = sdbus::createPlainMessage(); + + enum class EnumA : int16_t {X = 5} aWritten{EnumA::X}; + enum EnumB {Y = 11} bWritten{EnumB::Y}; + + msg << aWritten << bWritten; + msg.seal(); + + EnumA aRead{}; + EnumB bRead{}; + msg >> aRead >> bRead; + + ASSERT_THAT(aRead, Eq(aWritten)); + ASSERT_THAT(bRead, Eq(bWritten)); +} + TEST(AMessage, ThrowsWhenDestinationStdArrayIsTooSmallDuringDeserialization) { auto msg = sdbus::createPlainMessage(); diff --git a/tests/unittests/TypeTraits_test.cpp b/tests/unittests/TypeTraits_test.cpp index 169aa2d..662f472 100644 --- a/tests/unittests/TypeTraits_test.cpp +++ b/tests/unittests/TypeTraits_test.cpp @@ -49,6 +49,21 @@ namespace static std::string getDBusTypeSignature(); }; + enum class SomeEnumClass : uint8_t + { + A, B, C + }; + + enum struct SomeEnumStruct : int64_t + { + A, B, C + }; + + enum SomeClassicEnum + { + A, B, C + }; + #define TYPE(...) \ template <> \ std::string Type2DBusTypeSignatureConversion<__VA_ARGS__>::getDBusTypeSignature() \ @@ -79,8 +94,11 @@ namespace TYPE(std::vector)HAS_DBUS_TYPE_SIGNATURE("an") TYPE(std::array)HAS_DBUS_TYPE_SIGNATURE("an") #if __cplusplus >= 202002L - TYPE(std::span)HAS_DBUS_TYPE_SIGNATURE("ao") + TYPE(std::span)HAS_DBUS_TYPE_SIGNATURE("an") #endif + TYPE(SomeEnumClass)HAS_DBUS_TYPE_SIGNATURE("y") + TYPE(SomeEnumStruct)HAS_DBUS_TYPE_SIGNATURE("x") + TYPE(SomeClassicEnum)HAS_DBUS_TYPE_SIGNATURE("u") TYPE(std::map)HAS_DBUS_TYPE_SIGNATURE("a{ix}") TYPE(std::unordered_map)HAS_DBUS_TYPE_SIGNATURE("a{ix}") using ComplexType = std::map< @@ -127,6 +145,9 @@ namespace #if __cplusplus >= 202002L , std::span #endif + , SomeEnumClass + , SomeEnumStruct + , SomeClassicEnum , std::map , std::unordered_map , ComplexType