Uses different pass count for different parallel queue test cases
[libcds.git] / cds / opt / compare.h
index 6373a7ec109ec6449cfb4826d763b07944142f64..23c9cbdcc3d13adb3be7651bbc94e5dd8ddae8e8 100644 (file)
@@ -1,7 +1,35 @@
-//$$CDS-header$$
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
 
-#ifndef __CDS_OPT_COMPARE_H
-#define __CDS_OPT_COMPARE_H
+#ifndef CDSLIB_OPT_COMPARE_H
+#define CDSLIB_OPT_COMPARE_H
 
 /*
     Editions:
@@ -19,9 +47,9 @@ namespace cds { namespace opt {
     /**
         The option sets a type of a functor to compare keys.
         For comparing two keys \p k1 and \p k2 the functor must return:
-        - 1 if k1 > k2
-        - 0 if k1 == k2
-        - -1 if k1 < k2
+        - 1 if <tt> k1 > k2 </tt>
+        - 0 if <tt> k1 == k2 </tt>
+        - -1 if <tt> k1 < k2 </tt>
 
         \p Functor is a functor with following interface:
         \code
@@ -36,12 +64,12 @@ namespace cds { namespace opt {
         Note that the functor must return \p int, not a \p bool value.
 
         There are predefined type for \p Functor:
-        - the functor v::less_comparator that implements comparing functor through \p std::less predicate.
-        - the specialization of v::less_comparator functor intended for the string comparison
+        - the functor \p opt::v::less_comparator that implements comparing functor through \p std::less predicate.
+        - the specialization of \p opt::v::less_comparator functor intended for the string comparison
 
         You may implement your own comparing functor that satisfies \p Functor interface.
 
-        About relation between \ref opt::less and \ref opt::compare option setters see opt::less description.
+        About relation between \p %opt::less and \p %opt::compare option setters see \p opt::less description.
     */
     template <typename Functor>
     struct compare {
@@ -65,7 +93,7 @@ namespace cds { namespace opt {
             /// Operator that compares two value of type \p T
             int operator()(T const& v1, T const& v2)
             {
-                if ( std::less<T>()( v1, v2 ) )
+                if ( std::less<T>()( v1, v2 ))
                     return -1;
                 if ( std::less<T>()( v2, v1 ))
                     return 1;
@@ -75,7 +103,7 @@ namespace cds { namespace opt {
 
         /// Comparator specialization for \p std::string
         /**
-            This functor uses \p std::string::compare method instead of \p std::less predicate.
+            This functor uses \p std::string::compare() method instead of \p std::less predicate.
         */
         template <typename T, typename Traits, typename Alloc>
         struct less_comparator< std::basic_string<T, Traits, Alloc> >
@@ -121,11 +149,11 @@ namespace cds { namespace opt {
 
         Generally, the default type for \p Functor is \p std::less but it depends on the container used.
 
-        \par Relation between \p opt::less and opt::compare option setters
-        Unless otherwise specified, \p compare option setter has high priority. If opt::compare and opt::less options are specified
-        for a container, the opt::compare option is used:
+        \par Relation between opt::less and opt::compare option setters
+        Unless otherwise specified, \p opt::compare option setter has high priority.
+        If \p %opt::compare and \p %opt::less options are specified for a container, the \p %opt::compare option is used:
         \code
-        // Suppose, hypothetical map_type allows to specify
+        // Suppose, hypothetical map_type allows to specify
         // cds::opt::less and cds::opt::compare options
 
         typedef map_type< std::string, int,
@@ -158,16 +186,16 @@ namespace cds { namespace opt {
             int operator ()( T const& t, Q const& q ) const
             {
                 less_functor f;
-                if ( f( t, q ) )
+                if ( f( t, q ))
                     return -1;
-                if ( f( q, t ) )
+                if ( f( q, t ))
                     return 1;
                 return 0;
             }
         };
 
-        template <typename T, typename Traits, bool Forced = true >
-        struct make_comparator
+        template <typename T, typename Traits, typename DefaultCmp = make_comparator_from_less< std::less<T>> >
+        struct make_comparator_from
         {
             typedef typename Traits::compare compare;
             typedef typename Traits::less less;
@@ -176,14 +204,23 @@ namespace cds { namespace opt {
                 std::is_same< compare, opt::none >::value,
                 typename std::conditional<
                     std::is_same< less, opt::none >::value,
-                    typename std::conditional< Forced, make_comparator_from_less< std::less<T> >, opt::none >::type,
+                    DefaultCmp,
                     make_comparator_from_less< less >
                 >::type,
                 compare
             >::type type;
         };
 
-        template <typename T, CDS_DECL_OPTIONS>
+
+        template <typename T, typename Traits, bool Forced = true >
+        using make_comparator = make_comparator_from< T, Traits,
+            typename std::conditional<
+                Forced,
+                make_comparator_from_less< std::less<T>>,
+                opt::none
+            >::type >;
+
+        template <typename T, typename... Options>
         struct make_comparator_from_option_list
         {
             struct default_traits {
@@ -193,15 +230,15 @@ namespace cds { namespace opt {
 
             typedef typename make_comparator< T,
                 typename opt::make_options<
-                    typename opt::find_type_traits< default_traits, CDS_OPTIONS >::type
-                    ,CDS_OPTIONS
+                    typename opt::find_type_traits< default_traits, Options... >::type
+                    ,Options...
                 >::type
             >::type type;
         };
     }   // namespace details
     //@endcond
 
-    /// [type-option] Option setter for \p equal_to predicate
+    /// [type-option] Option setter for \p opt::equal_to predicate
     /**
         The option sets a binary predicate that tests whether a value of a specified type is equal to another value of that type.
         \p Functor interface is similar to \p std::equal_to predicate interface.
@@ -244,14 +281,50 @@ 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
+            {
+                return compare_functor()(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,
+                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;
         };
@@ -260,4 +333,4 @@ namespace cds { namespace opt {
 
 }}  // namespace cds::opt
 
-#endif // #ifndef __CDS_OPT_COMPARE_H
+#endif // #ifndef CDSLIB_OPT_COMPARE_H