Support sort option in nonintrusive and kv lists.
authorMike Krinkin <krinkin.m.u@gmail.com>
Sat, 28 Mar 2015 10:02:13 +0000 (13:02 +0300)
committerMike Krinkin <krinkin.m.u@gmail.com>
Sat, 28 Mar 2015 11:24:43 +0000 (14:24 +0300)
Nonintrusive lazy list and key-value list use intrusive lazy list
as backend, so implementation is pretty simple.

cds/container/details/make_lazy_kvlist.h
cds/container/details/make_lazy_list.h
cds/container/lazy_kvlist_nogc.h
cds/container/lazy_list_nogc.h

index 5b0131824c16b24b21998735c36e78785c4abfc8..f27f44602a2890a5be6463dcea954d3634b40feb 100644 (file)
@@ -64,6 +64,7 @@ namespace cds { namespace container {
             };
 
             typedef typename opt::details::make_comparator< key_type, original_type_traits >::type key_comparator;
+            typedef typename opt::details::make_equal_to< key_type, original_type_traits >::type equal_to_comparator;
 
             template <typename Less>
             struct less_wrapper {
@@ -75,6 +76,7 @@ namespace cds { namespace container {
                 typedef intrusive::lazy_list::base_hook< opt::gc<gc> >  hook;
                 typedef node_deallocator disposer;
                 typedef cds::details::compare_wrapper< node_type, key_comparator, key_field_accessor > compare;
+                typedef cds::details::predicate_wrapper< node_type, equal_to_comparator, key_field_accessor > equal_to;
                 static const opt::link_check_type link_checker = cds::intrusive::lazy_list::traits::link_checker;
             };
 
index ee853a61326e11d5baf145244f3b4d551f344beb..215d7ce467b800afbafa4732f13259e2de9cb697 100644 (file)
@@ -46,6 +46,7 @@ namespace cds { namespace container {
             };
 
             typedef typename opt::details::make_comparator< value_type, original_type_traits >::type key_comparator;
+            typedef typename opt::details::make_equal_to< value_type, original_type_traits >::type equal_to_comparator;
 
             struct value_accessor {
                 value_type const & operator()( node_type const & node ) const
@@ -66,6 +67,7 @@ namespace cds { namespace container {
                 static CDS_CONSTEXPR const opt::link_check_type link_checker = cds::intrusive::lazy_list::traits::link_checker;
 
                 typedef cds::details::compare_wrapper< node_type, key_comparator, value_accessor > compare;
+                typedef cds::details::predicate_wrapper< node_type, equal_to_comparator, value_accessor > equal_to;
             };
 
             typedef intrusive::LazyList<gc, node_type, intrusive_traits>  type;
index 7a93b72e1f6ee0c10b8354941ef6f33d2c88e2e7..3f8c67b0740b2b7f8b6c448c590241f9db68d829 100644 (file)
@@ -41,6 +41,7 @@ namespace cds { namespace container {
         //@endcond
 
     public:
+        typedef Traits traits;
         typedef cds::gc::nogc gc; ///< Garbage collector
 #ifdef CDS_DOXYGEN_INVOKED
         typedef Key                                 key_type        ;   ///< Key type
@@ -59,11 +60,11 @@ namespace cds { namespace container {
 
     protected:
         //@cond
-        typedef typename base_class::value_type   node_type;
-        typedef typename maker::cxx_allocator     cxx_allocator;
-        typedef typename maker::node_deallocator  node_deallocator;
-        typedef typename maker::intrusive_traits::compare  intrusive_key_comparator;
-        typedef typename base_class::node_type    head_type;
+        typedef typename base_class::value_type     node_type;
+        typedef typename maker::cxx_allocator       cxx_allocator;
+        typedef typename maker::node_deallocator    node_deallocator;
+        typedef typename base_class::predicate_type intrusive_predicate_type;
+        typedef typename base_class::node_type      head_type;
         //@endcond
 
     protected:
@@ -408,7 +409,7 @@ namespace cds { namespace container {
         template <typename Q>
         iterator find( Q const& key )
         {
-            return node_to_iterator( find_at( head(), key, intrusive_key_comparator() ) );
+            return node_to_iterator( find_at( head(), key, intrusive_predicate_type() ) );
         }
 
         /// Finds the key \p val using \p pred predicate for searching
@@ -418,8 +419,8 @@ namespace cds { namespace container {
             \p Less functor has the interface like \p std::less.
             \p pred must imply the same element order as the comparator used for building the list.
         */
-        template <typename Q, typename Less>
-        iterator find_with( Q const& key, Less pred )
+        template <typename Q, typename Less, bool Sort = traits::sort>
+        typename std::enable_if<Sort, iterator>::type find_with( Q const& key, Less pred )
         {
             CDS_UNUSED( pred );
             return node_to_iterator( find_at( head(), key, typename maker::template less_wrapper<Less>::type() ) );
index f3ed777d039411033bf634364082c686257dde12..497c88c813ca57eb311013bdcc1f9bfbff8c1c32 100644 (file)
@@ -44,18 +44,19 @@ namespace cds { namespace container {
         typedef T      value_type; ///< Type of value stored in the list
         typedef Traits traits;     ///< List traits
 
-        typedef typename base_class::back_off     back_off;       ///< Back-off strategy used
-        typedef typename maker::allocator_type    allocator_type; ///< Allocator type used for allocate/deallocate the nodes
-        typedef typename base_class::item_counter item_counter;   ///< Item counting policy used
-        typedef typename maker::key_comparator    key_comparator; ///< key comparison functor
-        typedef typename base_class::memory_model memory_model;   ///< Memory ordering. See cds::opt::memory_model option
+        typedef typename base_class::back_off       back_off;            ///< Back-off strategy used
+        typedef typename maker::allocator_type      allocator_type;      ///< Allocator type used for allocate/deallocate the nodes
+        typedef typename base_class::item_counter   item_counter;        ///< Item counting policy used
+        typedef typename maker::key_comparator      key_comparator;      ///< key comparison functor
+        typedef typename maker::equal_to_comparator equal_to_comparator; ///< key equality comparision functor
+        typedef typename base_class::memory_model   memory_model;        ///< Memory ordering. See cds::opt::memory_model option
 
     protected:
         //@cond
-        typedef typename base_class::value_type   node_type;
-        typedef typename maker::cxx_allocator     cxx_allocator;
-        typedef typename maker::node_deallocator  node_deallocator;
-        typedef typename maker::intrusive_traits::compare intrusive_key_comparator;
+        typedef typename base_class::value_type     node_type;
+        typedef typename maker::cxx_allocator       cxx_allocator;
+        typedef typename maker::node_deallocator    node_deallocator;
+        typedef typename base_class::predicate_type intrusive_predicate_type;
 
         typedef typename base_class::node_type      head_type;
         //@endcond
@@ -315,7 +316,7 @@ namespace cds { namespace container {
         template <typename Q>
         iterator find( Q const& key )
         {
-            return node_to_iterator( find_at( head(), key, intrusive_key_comparator() ));
+            return node_to_iterator( find_at( head(), key, intrusive_predicate_type() ));
         }
 
         /// Finds the key \p val using \p pred predicate for searching
@@ -325,8 +326,8 @@ namespace cds { namespace container {
             \p Less functor has the interface like \p std::less.
             \p pred must imply the same element order as the comparator used for building the list.
         */
-        template <typename Q, typename Less>
-        iterator find_with( Q const& key, Less pred )
+        template <typename Q, typename Less, bool Sort = traits::sort>
+        typename std::enable_if<Sort, iterator>::type find_with( Q const& key, Less pred )
         {
             CDS_UNUSED( pred );
             return node_to_iterator( find_at( head(), key, typename maker::template less_wrapper<Less>::type() ));