GAPI: utils - variant::get_if
authorAnton Potapov <potapov.slash.co@gmail.com>
Mon, 13 Apr 2020 08:17:08 +0000 (11:17 +0300)
committerAnton Potapov <anton.potapov@intel.com>
Tue, 14 Apr 2020 12:12:31 +0000 (15:12 +0300)
adding one more missing function to local version of std::variant

modules/gapi/include/opencv2/gapi/util/variant.hpp
modules/gapi/test/util/variant_tests.cpp

index 22dfb2e..6e6a73b 100644 (file)
@@ -150,6 +150,9 @@ namespace util
     protected:
         template<typename T, typename... Us> friend T& get(variant<Us...> &v);
         template<typename T, typename... Us> friend const T& get(const variant<Us...> &v);
+        template<typename T, typename... Us> friend T* get_if(variant<Us...> *v) noexcept;
+        template<typename T, typename... Us> friend const T* get_if(const variant<Us...> *v) noexcept;
+
         template<typename... Us> friend bool operator==(const variant<Us...> &lhs,
                                                         const variant<Us...> &rhs);
         Memory memory;
@@ -201,6 +204,11 @@ namespace util
     };
 
     // FIMXE: visit
+    template<typename T, typename... Types>
+    T* get_if(util::variant<Types...>* v) noexcept;
+
+    template<typename T, typename... Types>
+    const T* get_if(const util::variant<Types...>* v) noexcept;
 
     template<typename T, typename... Types>
     T& get(util::variant<Types...> &v);
@@ -335,27 +343,43 @@ namespace util
     }
 
     template<typename T, typename... Types>
-    T& get(util::variant<Types...> &v)
+    T* get_if(util::variant<Types...>* v) noexcept
     {
         const constexpr std::size_t t_index =
             util::type_list_index<T, Types...>::value;
 
-        if (v.index() == t_index)
-            return *(T*)(&v.memory);  // workaround for ICC 2019
+        if (v && v->index() == t_index)
+            return (T*)(&v->memory);  // workaround for ICC 2019
             // original code: return reinterpret_cast<T&>(v.memory);
-        else
-            throw_error(bad_variant_access());
+        return nullptr;
     }
 
     template<typename T, typename... Types>
-    const T& get(const util::variant<Types...> &v)
+    const T* get_if(const util::variant<Types...>* v) noexcept
     {
         const constexpr std::size_t t_index =
             util::type_list_index<T, Types...>::value;
 
-        if (v.index() == t_index)
-            return *(const T*)(&v.memory);  // workaround for ICC 2019
+        if (v && v->index() == t_index)
+            return (const T*)(&v->memory);  // workaround for ICC 2019
             // original code: return reinterpret_cast<const T&>(v.memory);
+        return nullptr;
+    }
+
+    template<typename T, typename... Types>
+    T& get(util::variant<Types...> &v)
+    {
+        if (auto* p = get_if<T>(&v))
+            return *p;
+        else
+            throw_error(bad_variant_access());
+    }
+
+    template<typename T, typename... Types>
+    const T& get(const util::variant<Types...> &v)
+    {
+        if (auto* p = get_if<T>(&v))
+            return *p;
         else
             throw_error(bad_variant_access());
     }
index 41aa4af..69f88b3 100644 (file)
@@ -289,6 +289,22 @@ TEST(Variant, Swap_DiffIndex)
     EXPECT_EQ(3.14f, util::get<float>(tv1));
 }
 
+TEST(Variant, GetIf)
+{
+    const TestVar cv(42);
+
+    // Test const& get_if()
+    EXPECT_EQ(nullptr, util::get_if<std::string>(&cv));
+    ASSERT_NE(nullptr, util::get_if<int>(&cv));
+    EXPECT_EQ(42, *util::get_if<int>(&cv));
+
+    // Test &get_if
+    TestVar cv2(std::string("42"));
+    EXPECT_EQ(nullptr, util::get_if<int>(&cv2));
+    ASSERT_NE(nullptr, util::get_if<std::string>(&cv2));
+    EXPECT_EQ("42", *util::get_if<std::string>(&cv2));
+}
+
 TEST(Variant, Get)
 {
     const TestVar cv(42);