Added utility functions getAllProperties and unpackProperties

Tested:
  - Added example to verify that functions work correctly
  - Added new unit tests that are passing
  - All other tests are still passing after this change
  - Added handling of new type (std::monostate) which can
    be used as first type in variant to represent that none
    of the other types was matched

Change-Id: Ic8e7c8d3116d64b94be37147ae8a80ebb5d3811d
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/test/utility/type_traits.cpp b/test/utility/type_traits.cpp
index 58ade36..33bf8c1 100644
--- a/test/utility/type_traits.cpp
+++ b/test/utility/type_traits.cpp
@@ -2,7 +2,7 @@
 
 #include <type_traits>
 
-#include <gtest/gtest.h>
+#include <gmock/gmock.h>
 
 namespace
 {
@@ -26,4 +26,60 @@
                   "array_to_ptr_t<int, char[100]> != char[100]");
 }
 
+TEST(TypeTraits, HasMemberFind)
+{
+    using sdbusplus::utility::has_member_find_v;
+    using namespace testing;
+
+    ASSERT_THAT((has_member_find_v<std::map<std::string, int>>), Eq(true));
+    ASSERT_THAT((has_member_find_v<std::vector<std::pair<std::string, int>>>),
+                Eq(false));
+
+    struct Foo
+    {
+        using value_type = std::pair<int, int>;
+
+        void find(std::tuple_element_t<0, value_type>)
+        {}
+    };
+
+    struct Bar
+    {};
+
+    ASSERT_THAT(has_member_find_v<Foo>, Eq(true));
+    ASSERT_THAT(has_member_find_v<Foo&>, Eq(true));
+    ASSERT_THAT(has_member_find_v<const Foo&>, Eq(true));
+
+    ASSERT_THAT(has_member_find_v<Bar>, Eq(false));
+}
+
+TEST(TypeTraits, HasMemberContains)
+{
+    using sdbusplus::utility::has_member_contains_v;
+    using namespace testing;
+
+    // std::map has member_contains from c++20
+    ASSERT_THAT((has_member_contains_v<std::map<std::string, int>>), Eq(false));
+    ASSERT_THAT(
+        (has_member_contains_v<std::vector<std::pair<std::string, int>>>),
+        Eq(false));
+
+    struct Foo
+    {
+        using value_type = std::pair<int, int>;
+
+        void contains(std::tuple_element_t<0, value_type>)
+        {}
+    };
+
+    struct Bar
+    {};
+
+    ASSERT_THAT(has_member_contains_v<Foo>, Eq(true));
+    ASSERT_THAT(has_member_contains_v<Foo&>, Eq(true));
+    ASSERT_THAT(has_member_contains_v<const Foo&>, Eq(true));
+
+    ASSERT_THAT(has_member_contains_v<Bar>, Eq(false));
+}
+
 } // namespace