Derive equal_to from compare/less functors.
authorMike Krinkin <krinkin.m.u@gmail.com>
Sat, 28 Mar 2015 06:58:27 +0000 (09:58 +0300)
committerMike Krinkin <krinkin.m.u@gmail.com>
Sat, 28 Mar 2015 06:58:27 +0000 (09:58 +0300)
For unordered lists it is possible to derive equal_to from compare
or less functors. This patch fixes make_equal_to so that it
returns equal_to if it is specified, else if compare is specified
it derives equal_to from compare functor, otherwise it derives
equal_to from less functor.

cds/opt/compare.h

index 3bcfc9617e2c8c831c6193b62b8549f231ca156e..1243f5be3777fe996c483a84784e71c483c0471f 100644 (file)
@@ -244,16 +244,52 @@ namespace cds { namespace opt {
 
     //@cond
     namespace details {
+        template <typename Compare>
+        struct make_equal_to_from_compare
+        {
+            typedef Compare compare_functor;
+
+            template <typename T, typename Q>
+            bool operator()( T const& t, Q const& q ) const
+            {
+                compare_functor cmp;
+                return cmp(t, q) == 0;
+            }
+        };
+
+        template <typename Less>
+        struct make_equal_to_from_less
+        {
+            typedef Less less_functor;
+
+            template <typename T, typename Q>
+            bool operator()( T const& t, Q const& q ) const
+            {
+                less_functor less;
+                return !less(t, q) && !less(q, t);
+            }
+        };
+
         template <typename T, typename Traits, bool Forced = true>
         struct make_equal_to
         {
             typedef typename Traits::equal_to equal_to;
+            typedef typename Traits::compare  compare;
+            typedef typename Traits::less     less;
 
             typedef typename std::conditional<
                 std::is_same< equal_to, opt::none >::value,
-                typename std::conditional< Forced, std::equal_to<T>, opt::none >::type,
-                equal_to
-            >::type type;
+                typename std::conditional<
+                    std::is_same< compare, opt::none >::value,
+                    typename std::conditional<
+                        std::is_same< less, opt::none >::value,
+                        typename std::conditional<
+                            Forced,
+                            std::equal_to<T>,
+                            opt::none >::type,
+                        make_equal_to_from_less< less > >::type,
+                    make_equal_to_from_compare< compare > >::type,
+                equal_to >::type type;
         };
     }
     //@endcond