message: template to check if convert_from_string exists
Add a SFINAE template to determine if convert_from_string
exists for a type.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I5202dacd50734e06a02955ed613e124d8fe0127f
diff --git a/include/sdbusplus/message/native_types.hpp b/include/sdbusplus/message/native_types.hpp
index 1f77914..2624d34 100644
--- a/include/sdbusplus/message/native_types.hpp
+++ b/include/sdbusplus/message/native_types.hpp
@@ -221,6 +221,26 @@
return details::convert_to_string<T>::op(t);
}
+namespace details
+{
+// SFINAE templates to determine if convert_from_string exists for a type.
+template <typename T>
+auto has_convert_from_string_helper(T)
+ -> decltype(convert_from_string<T>::op(std::declval<std::string>()),
+ std::true_type());
+auto has_convert_from_string_helper(...) -> std::false_type;
+
+template <typename T>
+struct has_convert_from_string :
+ decltype(has_convert_from_string_helper(std::declval<T>()))
+{};
+
+template <typename T>
+inline constexpr bool has_convert_from_string_v =
+ has_convert_from_string<T>::value;
+
+} // namespace details
+
} // namespace message
} // namespace sdbusplus
diff --git a/test/server/message_variant.cpp b/test/server/message_variant.cpp
index 4c3ea0e..2fa44b7 100644
--- a/test/server/message_variant.cpp
+++ b/test/server/message_variant.cpp
@@ -43,6 +43,15 @@
}
};
+static_assert(
+ sdbusplus::message::details::has_convert_from_string_v<TestIf::EnumOne>,
+ "EnumOne does not have convert_from_string!");
+static_assert(
+ sdbusplus::message::details::has_convert_from_string_v<TestIf::EnumTwo>,
+ "EnumTwo does not have convert_from_string!");
+static_assert(!sdbusplus::message::details::has_convert_from_string_v<size_t>,
+ "size_t unexpectedly has a convert_from_string!");
+
TEST_F(Object, PlainEnumOne)
{
run_test<TestIf::EnumOne>(TestIf::EnumOne::OneA);