Changed operator T enable_if to be more closely linked to the variant
authorErich Keane <erich.keane@intel.com>
Tue, 3 Nov 2015 17:53:42 +0000 (09:53 -0800)
committerHabib Virji <habib.virji@samsung.com>
Wed, 4 Nov 2015 21:08:27 +0000 (21:08 +0000)
The link between the variant and the enable_if needs to be strong!
Previously, there was no direct link, just one by 'coincidence'.  This
patch introduces a pair of type traits that bind the enable_if directly
to the variant.  Note that the type traits also work with ANY variadic
type!

Change-Id: Ie5f8fbc92b4f6800625c58fd73c08bedf147f122
Signed-off-by: Erich Keane <erich.keane@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/4021
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Ossama Othman <ossama.othman@intel.com>
Reviewed-by: Habib Virji <habib.virji@samsung.com>
resource/include/OCRepresentation.h
resource/include/OCUtilities.h

index 84e88e5..f47daf1 100644 (file)
@@ -266,27 +266,10 @@ namespace OC
                     // ambigious conversions in the case where conversions can include a number of
                     // types, such as the string constructor.
                     template<typename T, typename std::enable_if<
-                     std::is_same<T, int>::value ||
-                     std::is_same<T, double>::value ||
-                     std::is_same<T, bool>::value ||
-                     std::is_same<T, std::string>::value ||
-                     std::is_same<T, OCRepresentation>::value ||
-                     std::is_same<T, std::vector<int>>::value ||
-                     std::is_same<T, std::vector<std::vector<int>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<int>>>>::value ||
-                     std::is_same<T, std::vector<double>>::value ||
-                     std::is_same<T, std::vector<std::vector<double>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<double>>>>::value ||
-                     std::is_same<T, std::vector<bool>>::value ||
-                     std::is_same<T, std::vector<std::vector<bool>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<bool>>>>::value ||
-                     std::is_same<T, std::vector<std::string>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::string>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<std::string>>>>::value ||
-                     std::is_same<T, std::vector<OCRepresentation>>::value ||
-                     std::is_same<T, std::vector<std::vector<OCRepresentation>>>::value ||
-                     std::is_same<T, std::vector<std::vector<std::vector<OCRepresentation>>>>::value
-                     , int>::type = 0// enable_if
+                        is_component<T,
+                            remove_first<AttributeValue>::type
+                            >::value
+                        , int>::type = 0
                     >
                     operator T() const
                     {
index 87bdf35..8c7c34f 100644 (file)
@@ -112,6 +112,36 @@ namespace OC
     {
         constexpr static bool value = true;
     };
+
+    // type trait to remove the first type from a parameter-packed list
+    template <typename T>
+    struct remove_first;
+
+    // specialization that does all the work
+    template<template <typename...> class Base, typename T, typename ...Rest>
+    struct remove_first< Base<T, Rest...> >
+    {
+        typedef Base<Rest...> type;
+    };
+
+    // type trait that will only pass if ToTest is in the parameter pack of T2
+    template<typename ToTest, typename T2>
+    struct is_component;
+
+    // specialization to handle the single-item case
+    template<typename ToTest, template <typename...> class Base, typename T>
+    struct is_component<ToTest, Base<T>>
+    {
+        static constexpr bool value = std::is_same<ToTest, T>::value;
+    };
+
+    // Recursive specialization to handle cases with multiple values
+    template<typename ToTest, template <typename...> class Base, typename T, typename ...Rest>
+    struct is_component<ToTest, Base<T, Rest...>>
+    {
+        static constexpr bool value = std::is_same<ToTest, T>::value
+            || is_component<ToTest, Base<Rest...>>::value;
+    };
 } // namespace OC
 
 #endif