Refactored LazyList<nogc> with ordering option
authorkhizmax <khizmax@gmail.com>
Mon, 30 Mar 2015 13:30:28 +0000 (16:30 +0300)
committerkhizmax <khizmax@gmail.com>
Mon, 30 Mar 2015 13:30:28 +0000 (16:30 +0300)
cds/container/details/lazy_list_base.h
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
cds/intrusive/details/lazy_list_base.h
cds/intrusive/lazy_list_nogc.h
cds/opt/compare.h
tests/test-hdr/ordered_list/hdr_intrusive_lazy.h
tests/test-hdr/ordered_list/hdr_intrusive_lazy_nogc.cpp

index ad0ad2a8068bb6c742089c75c7c41ddbd1225ce0..ce53bdcb7554a6fc35251235147564589368e05c 100644 (file)
@@ -44,7 +44,7 @@ namespace cds { namespace container {
             /// Specifies list ordering policy.
             /**
                 If \p sort is \p true, than list maintains items in sorted order, otherwise items are unordered. Default is \p true.
-                Note that if \p sort is \p falsem than lookup operations scan entire list.
+                Note that if \p sort is \p false then lookup operations scan entire list.
             */
             static const bool sort = true;
 
index ff3ea15c2242507319ea0f1dc8cbc8df7bc3dba3..29555e87cf46e3e9b0106e6a1cdfea0a15d83f3c 100644 (file)
@@ -63,8 +63,11 @@ 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;
+            typedef typename std::conditional< original_type_traits::sort,
+                typename opt::details::make_comparator< value_type, original_type_traits >::type,
+                typename opt::details::make_equal_to< value_type, original_type_traits >::type
+            >::type key_comparator;
+
 
             template <typename Less>
             struct less_wrapper {
@@ -80,8 +83,17 @@ 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;
+
+                typedef typename std::conditional< std::is_same< typename original_type_traits::equal_to, cds::opt::none >::value,
+                    cds::opt::none,
+                    typename equal_to_wrapper< typename original_type_traits::equal_to >::type
+                >::type equal_to;
+
+                typedef typename std::conditional< original_type_traits::sort,
+                    cds::details::compare_wrapper< node_type, key_comparator, key_field_accessor >,
+                    cds::opt::none
+                >::type compare;
+
                 static const opt::link_check_type link_checker = cds::intrusive::lazy_list::traits::link_checker;
             };
 
index 578e484c14fd6b7d97ebd02667c336c40c7e8256..498b689e812ef88ecac88cde69517c3960fed6a3 100644 (file)
@@ -45,8 +45,10 @@ 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;
+            typedef typename std::conditional< original_type_traits::sort,
+                typename opt::details::make_comparator< value_type, original_type_traits >::type,
+                typename opt::details::make_equal_to< value_type, original_type_traits >::type
+            >::type key_comparator;
 
             struct value_accessor {
                 value_type const & operator()( node_type const & node ) const
@@ -71,8 +73,15 @@ namespace cds { namespace container {
                 typedef node_deallocator               disposer;
                 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 typename std::conditional< std::is_same< typename original_type_traits::equal_to, cds::opt::none >::value,
+                    cds::opt::none,
+                    typename equal_to_wrapper< typename original_type_traits::equal_to >::type
+                >::type equal_to;
+
+                typedef typename std::conditional< original_type_traits::sort,
+                    typedef cds::details::compare_wrapper< node_type, key_comparator, value_accessor >,
+                    cds::opt::none
+                >::type compare;
             };
 
             typedef intrusive::LazyList<gc, node_type, intrusive_traits>  type;
index d582180bd16dfb70be3355775c941ca92a30dc58..89d0a2ac95ba6a9175e763518e13c1cf468e1663 100644 (file)
@@ -57,13 +57,14 @@ namespace cds { namespace container {
         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
+        static CDS_CONSTEXPR bool const c_bSort = base_class::c_bSort; ///< List type: ordered (\p true) or unordered (\p false)
 
     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 base_class::predicate_type intrusive_predicate_type;
+        typedef typename base_class::key_comparator intrusive_key_comparator;
         typedef typename base_class::node_type      head_type;
         //@endcond
 
@@ -409,30 +410,30 @@ namespace cds { namespace container {
         template <typename Q>
         iterator find( Q const& key )
         {
-            return node_to_iterator( find_at( head(), key, intrusive_predicate_type() ) );
+            return node_to_iterator( find_at( head(), key, intrusive_key_comparator() ) );
         }
 
-        /// Finds the key \p val using \p pred predicate for searching
+        /// Finds the key \p val using \p pred predicate for searching (for ordered list only)
         /**
             The function is an analog of \ref cds_nonintrusive_LazyKVList_nogc_find "find(Q const&)"
             but \p pred is used for key comparing.
             \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, bool Sort = traits::sort>
+        template <typename Q, typename Less, bool Sort = c_bSort>
         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() ) );
         }
 
-        /// Finds the key \p val using \p equal predicate for searching
+        /// Finds the key \p val using \p equal predicate for searching (for unordered list only)
         /**
             The function is an analog of \ref cds_nonintrusive_LazyKVList_nogc_find "find(Q const&)"
             but \p equal is used for key comparing.
             \p Equal functor has the interface like \p std::equal_to.
         */
-        template <typename Q, typename Equal, bool Sort = traits::sort>
+        template <typename Q, typename Equal, bool Sort = c_bSort>
         typename std::enable_if<!Sort, iterator>::type find_with( Q const& key, Equal equal )
         {
             CDS_UNUSED( equal );
index 88860169c5c63fcd0e384b25506f886e37ccdaab..d32c84a7101505b2aef94a71f7b7f2ddee798b8b 100644 (file)
@@ -17,6 +17,11 @@ namespace cds { namespace container {
         This specialization is so-called append-only when no item
         reclamation may be performed. The class does not support deleting of list item.
 
+        The list can be ordered if \p Traits::sort is \p true that is default
+        or unordered otherwise. Unordered list can be maintained by \p equal_to
+        relationship (\p Traits::equal_to), but for the ordered list \p less
+        or \p compare relations should be specified in \p Traits.
+
         @copydetails cds_nonintrusive_LazyList_gc
     */
     template <
@@ -47,16 +52,16 @@ namespace cds { namespace container {
         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 maker::key_comparator      key_comparator;      ///< key comparing functor
         typedef typename base_class::memory_model   memory_model;        ///< Memory ordering. See cds::opt::memory_model option
+        static CDS_CONSTEXPR bool const c_bSort = base_class::c_bSort; ///< List type: ordered (\p true) or unordered (\p false)
 
     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 base_class::predicate_type intrusive_predicate_type;
+        typedef typename base_class::key_comparator intrusive_key_comparator;
 
         typedef typename base_class::node_type      head_type;
         //@endcond
@@ -316,30 +321,30 @@ namespace cds { namespace container {
         template <typename Q>
         iterator find( Q const& key )
         {
-            return node_to_iterator( find_at( head(), key, intrusive_predicate_type() ));
+            return node_to_iterator( find_at( head(), key, intrusive_key_comparator() ));
         }
 
-        /// Finds the key \p val using \p pred predicate for searching
+        /// Finds the key \p val using \p pred predicate for searching (only for ordered list)
         /**
             The function is an analog of \ref cds_nonintrusive_LazyList_nogc_find "find(Q const&)"
             but \p pred is used for key comparing.
             \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, bool Sort = traits::sort>
+        template <typename Q, typename Less, bool Sort = c_bSort>
         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() ));
         }
 
-        /// Finds the key \p val using \p equal predicate for searching
+        /// Finds the key \p val using \p equal predicate for searching (only for unordered list)
         /**
             The function is an analog of \ref cds_nonintrusive_LazyList_nogc_find "find(Q const&)"
             but \p pred is used for key comparing.
             \p Equal functor has the interface like \p std::equal_to.
         */
-        template <typename Q, typename Equal, bool Sort = traits::sort>
+        template <typename Q, typename Equal, bool Sort = c_bSort>
         typename std::enable_if<!Sort, iterator>::type find_with( Q const& key, Equal equal )
         {
             CDS_UNUSED( equal );
index bc6ff520c5820ce081865b4498d09001ae8de697..9f60c4313ad358c03b8856fcf9d3bdb7676349d6 100644 (file)
@@ -208,7 +208,7 @@ namespace cds { namespace intrusive {
             */
             typedef opt::none                       less;
 
-            /// Specifies binary functor used for comparing keys for equality
+            /// Specifies binary functor used for comparing keys for equality (for unordered list only)
             /**
                 If \p equal_to option is not specified, \p compare is used, if \p compare is not specified, \p less is used,
                 if \p less is not specified, then \p std::equal_to<T> is used.
@@ -217,7 +217,8 @@ namespace cds { namespace intrusive {
 
             /// Specifies list ordering policy
             /**
-                If \p sort is \p true, than list maintains items in sorted order, otherwise items are unordered. Default is \p true.
+                If \p sort is \p true, than list maintains items in sorted order, otherwise the list is unordered. 
+                Default is \p true.
                 Note that if \p sort is \p false, than lookup operations scan entire list.
             */
             static const bool sort = true;
index 467d795500dcae4a9a20a45f9b69182daba12f03..177d6819d563112bde64d0fbf871de23ab67f4e8 100644 (file)
@@ -40,13 +40,18 @@ namespace cds { namespace intrusive {
     }   // namespace lazy_list
 
 
-    /// Lazy ordered single-linked list (template specialization for \p gc::nogc)
+    /// Lazy single-linked list (template specialization for \p gc::nogc)
     /** @ingroup cds_intrusive_list
         \anchor cds_intrusive_LazyList_nogc
 
         This specialization is append-only list when no item
         reclamation may be performed. The class does not support deleting of list item.
 
+        The list can be ordered if \p Traits::sort is \p true that is default
+        or unordered otherwise. Unordered list can be maintained by \p equal_to
+        relationship (\p Traits::equal_to), but for the ordered list \p less
+        or \p compare relations should be specified in \p Traits.
+
         See \ref cds_intrusive_LazyList_hp "LazyList" for description of template parameters.
     */
     template <
@@ -66,15 +71,20 @@ namespace cds { namespace intrusive {
 
         typedef typename traits::hook    hook;      ///< hook type
         typedef typename hook::node_type node_type; ///< node type
+        static CDS_CONSTEXPR bool const c_bSort = traits::sort; ///< List type: ordered (\p true) or unordered (\p false)
 
 #   ifdef CDS_DOXYGEN_INVOKED
-        typedef implementation_defined key_comparator  ;    ///< key comparison functor based on opt::compare and opt::less option setter.
-        typedef implementation_defined equal_to_comparator;
-        typedef implementation_defined predicate_type;
+        /// Key comparing functor
+        /**
+            - for ordered list, the functor is based on \p traits::compare or \p traits::less
+            - for unordered list, the functor is based on \p traits::equal_to, \p traits::compare or \p traits::less
+        */
+        typedef implementation_defined key_comparator;
 #   else
-        typedef typename opt::details::make_comparator< value_type, traits >::type key_comparator;
-        typedef typename opt::details::make_equal_to< value_type, traits >::type equal_to_comparator;
-        typedef typename std::conditional< traits::sort, key_comparator, equal_to_comparator >::type predicate_type;
+        typedef typename std::conditional< c_bSort,
+            typename opt::details::make_comparator< value_type, traits >::type,
+            typename opt::details::make_equal_to< value_type, traits >::type
+        >::type key_comparator;
 #   endif
         typedef typename traits::back_off  back_off;   ///< Back-off strategy
         typedef typename traits::disposer  disposer;   ///< disposer
@@ -82,7 +92,7 @@ namespace cds { namespace intrusive {
         typedef typename lazy_list::get_link_checker< node_type, traits::link_checker >::type link_checker;   ///< link checker
 
         typedef typename traits::item_counter item_counter;  ///< Item counting policy used
-        typedef typename traits::memory_model  memory_model; ///< C++ memory ordering (see lazy_list::traits::memory_model)
+        typedef typename traits::memory_model memory_model; ///< C++ memory ordering (see lazy_list::traits::memory_model)
 
         //@cond
         // Rebind traits (split-list support)
@@ -386,13 +396,13 @@ namespace cds { namespace intrusive {
         template <typename Q, typename Func>
         bool find( Q& key, Func f )
         {
-            return find_at( &m_Head, key, predicate_type(), f );
+            return find_at( &m_Head, key, key_comparator(), f );
         }
         //@cond
         template <typename Q, typename Func>
         bool find( Q const& key, Func f )
         {
-            return find_at( &m_Head, key, predicate_type(), f );
+            return find_at( &m_Head, key, key_comparator(), f );
         }
         //@endcond
 
@@ -403,7 +413,7 @@ namespace cds { namespace intrusive {
             \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, typename Func, bool Sort = traits::sort>
+        template <typename Q, typename Less, typename Func, bool Sort = c_bSort>
         typename std::enable_if<Sort, bool>::type find_with( Q& key, Less less, Func f )
         {
             CDS_UNUSED( less );
@@ -416,25 +426,25 @@ namespace cds { namespace intrusive {
             but \p equal is used for key comparing.
             \p Equal functor has the interface like \p std::equal_to.
         */
-        template <typename Q, typename Equal, typename Func, bool Sort = traits::sort>
+        template <typename Q, typename Equal, typename Func, bool Sort = c_bSort>
         typename std::enable_if<!Sort, bool>::type find_with( Q& key, Equal equal, Func f )
         {
             CDS_UNUSED( equal );
-            return find_at( &m_Head, key, Equal(), f );
+            return find_at( &m_Head, key, equal, f );
         }
         //@cond
-        template <typename Q, typename Less, typename Func, bool Sort = traits::sort>
+        template <typename Q, typename Less, typename Func, bool Sort = c_bSort>
         typename std::enable_if<Sort, bool>::type find_with( Q const& key, Less pred, Func f )
         {
             CDS_UNUSED( pred );
             return find_at( &m_Head, key, cds::opt::details::make_comparator_from_less<Less>(), f );
         }
 
-        template <typename Q, typename Equal, typename Func, bool Sort = traits::sort>
+        template <typename Q, typename Equal, typename Func, bool Sort = c_bSort>
         typename std::enable_if<!Sort, bool>::type find_with( Q const& key, Equal equal, Func f )
         {
             CDS_UNUSED( equal );
-            return find_at( &m_Head, key, Equal(), f );
+            return find_at( &m_Head, key, equal, f );
         }
         //@endcond
 
@@ -446,7 +456,7 @@ namespace cds { namespace intrusive {
         template <typename Q>
         value_type * find( Q const& key )
         {
-            return find_at( &m_Head, key, predicate_type() );
+            return find_at( &m_Head, key, key_comparator() );
         }
 
         /// Finds the key \p key using \p pred predicate for searching. Disabled for unordered lists.
@@ -456,7 +466,7 @@ namespace cds { namespace intrusive {
             \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, bool Sort = traits::sort>
+        template <typename Q, typename Less, bool Sort = c_bSort>
         typename std::enable_if<Sort, value_type *>::type find_with( Q const& key, Less pred )
         {
             CDS_UNUSED( pred );
@@ -469,10 +479,9 @@ namespace cds { namespace intrusive {
             but \p equal is used for key comparing.
             \p Equal functor has the interface like \p std::equal_to.
         */
-        template <typename Q, typename Equal, bool Sort = traits::sort>
+        template <typename Q, typename Equal, bool Sort = c_bSort>
         typename std::enable_if<!Sort, value_type *>::type find_with( Q const& key, Equal equal )
         {
-            CDS_UNUSED( equal );
             return find_at( &m_Head, key, equal );
         }
 
@@ -547,7 +556,7 @@ namespace cds { namespace intrusive {
         {
             link_checker::is_empty( node_traits::to_node_ptr( val ) );
             position pos;
-            predicate_type pred;
+            key_comparator pred;
 
             while ( true ) {
                 search( pHead, val, pos, pred );
@@ -580,14 +589,14 @@ namespace cds { namespace intrusive {
         std::pair<iterator, bool> ensure_at_( node_type * pHead, value_type& val, Func func )
         {
             position pos;
-            predicate_type pred;
+            key_comparator pred;
 
             while ( true ) {
                 search( pHead, val, pos, pred );
                 {
                     auto_lock_position alp( pos );
                     if ( validate( pos.pPred, pos.pCur )) {
-                        if ( pos.pCur != &m_Tail && equal( *node_traits::to_value_ptr( *pos.pCur ), val, pred ) ) {
+                        if ( pos.pCur != &m_Tail && equal( *node_traits::to_value_ptr( *pos.pCur ), val, pred )) {
                             // key already in the list
 
                             func( false, *node_traits::to_value_ptr( *pos.pCur ) , val );
@@ -647,7 +656,7 @@ namespace cds { namespace intrusive {
 
             search( pHead, val, pos, pred );
             if ( pos.pCur != &m_Tail ) {
-                if ( equal( *node_traits::to_value_ptr( *pos.pCur ), val, pred ) )
+                if ( equal( *node_traits::to_value_ptr( *pos.pCur ), val, pred ))
                     return iterator( pos.pCur );
             }
             return end();
@@ -657,7 +666,7 @@ namespace cds { namespace intrusive {
 
     protected:
         //@cond
-        template <typename Q, typename Equal, bool Sort = traits::sort>
+        template <typename Q, typename Equal, bool Sort = c_bSort>
         typename std::enable_if<!Sort, void>::type search( node_type * pHead, const Q& key, position& pos, Equal eq )
         {
             const node_type * pTail = &m_Tail;
@@ -674,7 +683,7 @@ namespace cds { namespace intrusive {
             pos.pPred = pPrev;
         }
 
-        template <typename Q, typename Compare, bool Sort = traits::sort>
+        template <typename Q, typename Compare, bool Sort = c_bSort>
         typename std::enable_if<Sort, void>::type search( node_type * pHead, const Q& key, position& pos, Compare cmp )
         {
             const node_type * pTail = &m_Tail;
@@ -691,13 +700,13 @@ namespace cds { namespace intrusive {
             pos.pPred = pPrev;
         }
 
-        template <typename L, typename R, typename Equal, bool Sort = traits::sort>
+        template <typename L, typename R, typename Equal, bool Sort = c_bSort>
         static typename std::enable_if<!Sort, bool>::type equal( L const& l, R const& r, Equal eq )
         {
             return eq(l, r);
         }
 
-        template <typename L, typename R, typename Compare, bool Sort = traits::sort>
+        template <typename L, typename R, typename Compare, bool Sort = c_bSort>
         static typename std::enable_if<Sort, bool>::type equal( L const& l, R const& r, Compare cmp )
         {
             return cmp(l, r) == 0;
index 1243f5be3777fe996c483a84784e71c483c0471f..4e98955689ef38aec83a5c2b77e2f3d2066ed270 100644 (file)
@@ -252,8 +252,7 @@ namespace cds { namespace opt {
             template <typename T, typename Q>
             bool operator()( T const& t, Q const& q ) const
             {
-                compare_functor cmp;
-                return cmp(t, q) == 0;
+                return compare_functor()(t, q) == 0;
             }
         };
 
@@ -289,7 +288,8 @@ namespace cds { namespace opt {
                             opt::none >::type,
                         make_equal_to_from_less< less > >::type,
                     make_equal_to_from_compare< compare > >::type,
-                equal_to >::type type;
+                equal_to 
+            >::type type;
         };
     }
     //@endcond
index c8a7e1d0f668eeb373d9e6c81b0df9bd098dba49..f5e76040913f039c66b36ca753619f79fcd5fb07 100644 (file)
@@ -148,6 +148,26 @@ namespace ordlist {
             }
         };
 
+        template <typename T>
+        struct equal {
+            bool operator ()(const T& v1, const T& v2 ) const
+            {
+                return v1.key() == v2.key();
+            }
+
+            template <typename Q>
+            bool operator ()(const T& v1, const Q& v2 ) const
+            {
+                return v1.key() == v2;
+            }
+
+            template <typename Q>
+            bool operator ()(const Q& v1, const T& v2 ) const
+            {
+                return v1 == v2.key();
+            }
+        };
+
         struct other_item {
             int nKey;
 
@@ -164,6 +184,14 @@ namespace ordlist {
             }
         };
 
+        struct other_equal {
+            template <typename T, typename Q>
+            bool operator()( T const& i1, Q const& i2) const
+            {
+                return i1.nKey == i2.nKey;
+            }
+        };
+
         struct faked_disposer
         {
             template <typename T>
@@ -632,6 +660,8 @@ namespace ordlist {
         void test_nogc_int()
         {
             typedef typename OrdList::value_type    value_type;
+            typedef typename std::conditional< OrdList::c_bSort, less<value_type>, equal<value_type>>::type find_predicate;
+
             {
                 value_type v1( 10, 50 );
                 value_type v2( 5, 25  );
@@ -647,7 +677,7 @@ namespace ordlist {
                     CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
                     CPPUNIT_ASSERT( v1.s.nFindCall == 1 );
 
-                    CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>() ) == nullptr );
+                    CPPUNIT_ASSERT( l.find_with( v2.key(), find_predicate() ) == nullptr );
                     CPPUNIT_ASSERT( l.find( v3.key() ) == nullptr );
                     CPPUNIT_ASSERT( !l.empty() );
 
@@ -672,10 +702,10 @@ namespace ordlist {
                     CPPUNIT_ASSERT( l.find( v1.key(), find_functor() ));
                     CPPUNIT_ASSERT( v1.s.nFindCall == 2 );
 
-                    CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>() ) == &v2 );
+                    CPPUNIT_ASSERT( l.find_with( v2.key(), find_predicate() ) == &v2 );
 
                     CPPUNIT_ASSERT( v2.s.nFindCall == 0 );
-                    CPPUNIT_ASSERT( l.find_with( v2.key(), less<value_type>(), find_functor() ));
+                    CPPUNIT_ASSERT( l.find_with( v2.key(), find_predicate(), find_functor() ));
                     CPPUNIT_ASSERT( v2.s.nFindCall == 1 );
 
                     CPPUNIT_ASSERT( !l.find( v3.key() ));
@@ -815,6 +845,12 @@ namespace ordlist {
         void nogc_member_less();
         void nogc_member_cmpmix();
         void nogc_member_ic();
+        void nogc_base_unord_equal();
+        void nogc_base_unord_cmp();
+        void nogc_base_unord_less();
+        void nogc_member_unord_equal();
+        void nogc_member_unord_cmp();
+        void nogc_member_unord_less();
 
 
         CPPUNIT_TEST_SUITE(IntrusiveLazyListHeaderTest)
@@ -885,10 +921,16 @@ namespace ordlist {
             CPPUNIT_TEST(nogc_base_less)
             CPPUNIT_TEST(nogc_base_cmpmix)
             CPPUNIT_TEST(nogc_base_ic)
+            CPPUNIT_TEST(nogc_base_unord_equal)
+            CPPUNIT_TEST(nogc_base_unord_cmp)
+            CPPUNIT_TEST(nogc_base_unord_less)
             CPPUNIT_TEST(nogc_member_cmp)
             CPPUNIT_TEST(nogc_member_less)
             CPPUNIT_TEST(nogc_member_cmpmix)
             CPPUNIT_TEST(nogc_member_ic)
+            CPPUNIT_TEST(nogc_member_unord_equal)
+            CPPUNIT_TEST(nogc_member_unord_cmp)
+            CPPUNIT_TEST(nogc_member_unord_less)
 
         CPPUNIT_TEST_SUITE_END()
     };
index 6606ebee35a9272c5e3b355b0763b2e961b1cb12..4ce2686f9a0225938313c3bf7599954f448f817c 100644 (file)
@@ -15,6 +15,7 @@ namespace ordlist {
         typedef ci::LazyList< cds::gc::nogc, item, traits > list;
         test_nogc_int<list>();
     }
+
     void IntrusiveLazyListHeaderTest::nogc_base_less()
     {
         typedef base_int_item< cds::gc::nogc > item;
@@ -28,6 +29,7 @@ namespace ordlist {
         typedef ci::LazyList< cds::gc::nogc, item, traits > list;
         test_nogc_int<list>();
     }
+
     void IntrusiveLazyListHeaderTest::nogc_base_cmpmix()
     {
         typedef base_int_item< cds::gc::nogc > item;
@@ -42,6 +44,7 @@ namespace ordlist {
         >    list;
         test_nogc_int<list>();
     }
+
     void IntrusiveLazyListHeaderTest::nogc_base_ic()
     {
         typedef base_int_item< cds::gc::nogc > item;
@@ -57,6 +60,52 @@ namespace ordlist {
         >    list;
         test_nogc_int<list>();
     }
+
+    void IntrusiveLazyListHeaderTest::nogc_base_unord_equal()
+    {
+        typedef base_int_item< cds::gc::nogc > item;
+        struct traits: public
+            ci::lazy_list::make_traits<
+                ci::opt::hook< ci::lazy_list::base_hook< co::gc<cds::gc::nogc> > >
+                ,co::sort< false >
+                ,co::equal_to< equal<item> >
+                ,ci::opt::disposer< faked_disposer >
+            >::type
+        {};
+        typedef ci::LazyList< cds::gc::nogc, item, traits > list;
+        test_nogc_int<list>();
+    }
+
+    void IntrusiveLazyListHeaderTest::nogc_base_unord_cmp()
+    {
+        typedef base_int_item< cds::gc::nogc > item;
+        struct traits: public
+            ci::lazy_list::make_traits<
+                ci::opt::hook< ci::lazy_list::base_hook< co::gc<cds::gc::nogc> > >
+                ,co::sort< false >
+                ,co::compare< cmp<item> >
+                ,ci::opt::disposer< faked_disposer >
+            >::type
+        {};
+        typedef ci::LazyList< cds::gc::nogc, item, traits > list;
+        test_nogc_int<list>();
+    }
+
+    void IntrusiveLazyListHeaderTest::nogc_base_unord_less()
+    {
+        typedef base_int_item< cds::gc::nogc > item;
+        struct traits: public
+            ci::lazy_list::make_traits<
+                ci::opt::hook< ci::lazy_list::base_hook< co::gc<cds::gc::nogc> > >
+                ,co::sort< false >
+                ,co::less< less<item> >
+                ,ci::opt::disposer< faked_disposer >
+            >::type
+        {};
+        typedef ci::LazyList< cds::gc::nogc, item, traits > list;
+        test_nogc_int<list>();
+    }
+
     void IntrusiveLazyListHeaderTest::nogc_member_cmp()
     {
         typedef member_int_item< cds::gc::nogc > item;
@@ -73,6 +122,7 @@ namespace ordlist {
         >    list;
         test_nogc_int<list>();
     }
+
     void IntrusiveLazyListHeaderTest::nogc_member_less()
     {
         typedef member_int_item< cds::gc::nogc > item;
@@ -89,6 +139,7 @@ namespace ordlist {
         >    list;
         test_nogc_int<list>();
     }
+
     void IntrusiveLazyListHeaderTest::nogc_member_cmpmix()
     {
         typedef member_int_item< cds::gc::nogc > item;
@@ -106,6 +157,7 @@ namespace ordlist {
         >    list;
         test_nogc_int<list>();
     }
+
     void IntrusiveLazyListHeaderTest::nogc_member_ic()
     {
         typedef member_int_item< cds::gc::nogc > item;
@@ -124,4 +176,58 @@ namespace ordlist {
         test_nogc_int<list>();
     }
 
+    void IntrusiveLazyListHeaderTest::nogc_member_unord_equal()
+    {
+        typedef member_int_item< cds::gc::nogc > item;
+        typedef ci::LazyList< cds::gc::nogc
+            ,item
+            ,ci::lazy_list::make_traits<
+                ci::opt::hook< ci::lazy_list::member_hook<
+                    offsetof( item, hMember ),
+                    co::gc<cds::gc::nogc>
+                > >
+                ,co::sort< false >
+                ,co::equal_to< equal<item> >
+                ,ci::opt::disposer< faked_disposer >
+            >::type
+        >    list;
+        test_nogc_int<list>();
+    }
+
+    void IntrusiveLazyListHeaderTest::nogc_member_unord_cmp()
+    {
+        typedef member_int_item< cds::gc::nogc > item;
+        typedef ci::LazyList< cds::gc::nogc
+            ,item
+            ,ci::lazy_list::make_traits<
+                ci::opt::hook< ci::lazy_list::member_hook<
+                    offsetof( item, hMember ),
+                    co::gc<cds::gc::nogc>
+                > >
+                ,co::sort< false >
+                ,co::compare< cmp<item> >
+                ,ci::opt::disposer< faked_disposer >
+            >::type
+        >    list;
+        test_nogc_int<list>();
+    }
+
+    void IntrusiveLazyListHeaderTest::nogc_member_unord_less()
+    {
+        typedef member_int_item< cds::gc::nogc > item;
+        typedef ci::LazyList< cds::gc::nogc
+            ,item
+            ,ci::lazy_list::make_traits<
+                ci::opt::hook< ci::lazy_list::member_hook<
+                    offsetof( item, hMember ),
+                    co::gc<cds::gc::nogc>
+                > >
+                ,co::sort< false >
+                ,co::less< less<item> >
+                ,ci::opt::disposer< faked_disposer >
+            >::type
+        >    list;
+        test_nogc_int<list>();
+    }
+
 } // namespace ordlist