From: khizmax Date: Thu, 23 Oct 2014 17:55:16 +0000 (+0400) Subject: On dev: MIchaelList X-Git-Tag: v2.0.0~178^2 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7999eaee97df27c88866d1dfd130068dba955e88;p=libcds.git On dev: MIchaelList --- 7999eaee97df27c88866d1dfd130068dba955e88 diff --cc cds/container/details/make_michael_kvlist.h index 64a9d9b4,64a9d9b4..04cf1525 --- a/cds/container/details/make_michael_kvlist.h +++ b/cds/container/details/make_michael_kvlist.h @@@ -70,14 -70,14 +70,15 @@@ namespace cds { namespace container typedef cds::details::compare_wrapper< node_type, cds::opt::details::make_comparator_from_less, key_field_accessor > type; }; -- struct type_traits: public original_type_traits ++ struct intrusive_traits: public original_type_traits { typedef intrusive::michael_list::base_hook< opt::gc > hook; typedef node_deallocator disposer; typedef cds::details::compare_wrapper< node_type, key_comparator, key_field_accessor > compare; ++ static const opt::link_check_type link_checker = intrusive::michael_list::traits::link_checker; }; -- typedef intrusive::MichaelList type; ++ typedef intrusive::MichaelList type; }; } // namespace details //@endcond diff --cc cds/container/details/make_michael_list.h index 2c5939eb,2c5939eb..fd441b1c --- a/cds/container/details/make_michael_list.h +++ b/cds/container/details/make_michael_list.h @@@ -34,10 -34,10 +34,10 @@@ namespace cds { namespace container {} }; -- typedef Traits original_type_traits; ++ typedef Traits original_traits; -- typedef typename original_type_traits::allocator::template rebind::other allocator_type; -- typedef cds::details::Allocator< node_type, allocator_type > cxx_allocator; ++ typedef typename original_traits::allocator::template rebind::other allocator_type; ++ typedef cds::details::Allocator< node_type, allocator_type > cxx_allocator; struct node_deallocator { @@@ -47,7 -47,7 +47,7 @@@ } }; -- typedef typename opt::details::make_comparator< value_type, original_type_traits >::type key_comparator; ++ typedef typename opt::details::make_comparator< value_type, original_traits >::type key_comparator; struct value_accessor { @@@ -59,18 -59,18 +59,18 @@@ template struct less_wrapper { -- typedef cds::details::compare_wrapper< node_type, cds::opt::details::make_comparator_from_less, value_accessor > type; ++ typedef cds::details::compare_wrapper< node_type, cds::opt::details::make_comparator_from_less, value_accessor > type; }; -- struct type_traits: public original_type_traits ++ struct intrusive_traits: public original_traits { -- typedef intrusive::michael_list::base_hook< opt::gc > hook; -- typedef node_deallocator disposer; -- ++ typedef intrusive::michael_list::base_hook< opt::gc > hook; ++ typedef node_deallocator disposer; typedef cds::details::compare_wrapper< node_type, key_comparator, value_accessor > compare; ++ static const opt::link_check_type link_checker = intrusive::michael_list::traits::link_checker; }; -- typedef intrusive::MichaelList type; ++ typedef intrusive::MichaelList type; }; } // namespace details //@endcond diff --cc cds/container/details/michael_list_base.h index c30785ee,c30785ee..4660b5ff --- a/cds/container/details/michael_list_base.h +++ b/cds/container/details/michael_list_base.h @@@ -13,8 -13,8 +13,8 @@@ namespace cds { namespace container /** @ingroup cds_nonintrusive_helper */ namespace michael_list { -- /// Michael list default type traits -- struct type_traits ++ /// MichaelList traits ++ struct traits { typedef CDS_DEFAULT_ALLOCATOR allocator ; ///< allocator used to allocate new node @@@ -24,34 -24,34 +24,22 @@@ */ typedef opt::none compare; -- /// specifies binary predicate used for key comparison. ++ /// Specifies binary predicate used for key comparison. /** Default is \p std::less. */ typedef opt::none less; -- /// back-off strategy used -- /** -- If the option is not specified, the cds::backoff::empty is used. -- */ ++ /// Back-off strategy typedef cds::backoff::empty back_off; -- /// Item counter -- /** -- The type for item counting feature. -- Default is no item counter (\ref atomicity::empty_item_counter) -- */ ++ /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting typedef atomicity::empty_item_counter item_counter; -- /// Link fields checking feature -- /** -- Default is \ref intrusive::opt::debug_check_link -- */ -- static const opt::link_check_type link_checker = opt::debug_check_link; -- /// C++ memory ordering model -- /** -- List of available memory ordering see opt::memory_model ++ /** ++ Can be \p opt::v::relaxed_ordering (relaxed memory model, the default) ++ or \p opt::v::sequential_consistent (sequentially consisnent memory model). */ typedef opt::v::relaxed_ordering memory_model; @@@ -68,11 -68,11 +56,8 @@@ //@endcond }; -- /// Metafunction converting option list to MichaelList traits ++ /// Metafunction converting option list to \p michael_list::traits /** -- This is a wrapper for cds::opt::make_options< type_traits, Options...> -- -- See \ref MichaelList, \ref type_traits, \ref cds::opt::make_options. */ template struct make_traits { @@@ -80,7 -80,7 +65,7 @@@ typedef implementation_defined type ; ///< Metafunction result # else typedef typename cds::opt::make_options< -- typename cds::opt::find_type_traits< type_traits, Options... >::type ++ typename cds::opt::find_type_traits< traits, Options... >::type ,Options... >::type type; #endif @@@ -90,10 -90,10 +75,10 @@@ } // namespace michael_list // Forward declarations -- template ++ template class MichaelList; -- template ++ template class MichaelKVList; // Tag for selecting Michael's list implementation diff --cc cds/container/impl/michael_kvlist.h index 0043330d,0043330d..09623b03 --- a/cds/container/impl/michael_kvlist.h +++ b/cds/container/impl/michael_kvlist.h @@@ -4,12 -4,12 +4,11 @@@ #define __CDS_CONTAINER_IMPL_MICHAEL_KVLIST_H #include --#include // ref #include namespace cds { namespace container { -- /// Michael's ordered list (key-value pair) ++ /// Michael's ordered list fo key-value pair /** @ingroup cds_nonintrusive_list \anchor cds_nonintrusive_MichaelKVList_gc @@@ -18,16 -18,16 +17,17 @@@ constant key and alterable value. Usually, ordered single-linked list is used as a building block for the hash table implementation. -- The complexity of searching is O(N). ++ The complexity of searching is O(N) where \p N is the item count in the list, not in the ++ hash table. Template arguments: - \p GC - garbage collector used - \p Key - key type of an item stored in the list. It should be copy-constructible - \p Value - value type stored in a list -- - \p Traits - type traits, default is michael_list::type_traits ++ - \p Traits - type traits, default is \p michael_list::traits -- It is possible to declare option-based list with cds::container::michael_list::make_traits metafunction istead of \p Traits template -- argument. For example, the following traits-based declaration of gc::HP Michael's list ++ It is possible to declare option-based list with \p cds::container::michael_list::make_traits metafunction istead of \p Traits template ++ argument. For example, the following traits-based declaration of \p gc::HP Michael's list \code #include // Declare comparator for the item @@@ -38,8 -38,8 +38,8 @@@ } }; -- // Declare type_traits -- struct my_traits: public cds::container::michael_list::type_traits ++ // Declare traits ++ struct my_traits: public cds::container::michael_list::traits { typedef my_compare compare; }; @@@ -47,7 -47,7 +47,6 @@@ // Declare traits-based list typedef cds::container::MichaelKVList< cds::gc::HP, int, int, my_traits > traits_based_list; \endcode -- is equivalent for the following option-based list \code #include @@@ -62,16 -62,16 +61,6 @@@ > option_based_list; \endcode -- Template argument list \p Options of cds::container::michael_list::make_traits metafunction are: -- - opt::compare - key comparison functor. No default functor is provided. -- If the option is not specified, the opt::less is used. -- - opt::less - specifies binary predicate used for key comparison. Default is \p std::less. -- - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::empty is used. -- - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter that is no item counting. -- - opt::allocator - the allocator used for creating and freeing list's item. Default is \ref CDS_DEFAULT_ALLOCATOR macro. -- - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default) -- or opt::v::sequential_consistent (sequentially consisnent memory model). -- \par Usage There are different specializations of this template for each garbage collecting schema used. You should include appropriate .h-file depending on GC you are using: @@@ -85,7 -85,7 +74,7 @@@ typename Key, typename Value, #ifdef CDS_DOXYGEN_INVOKED -- typename Traits = michael_list::type_traits ++ typename Traits = michael_list::traits #else typename Traits #endif @@@ -98,8 -98,8 +87,8 @@@ #endif { //@cond -- typedef details::make_michael_kvlist< GC, Key, Value, Traits > options; -- typedef typename options::type base_class; ++ typedef details::make_michael_kvlist< GC, Key, Value, Traits > maker; ++ typedef typename maker::type base_class; //@endcond public: @@@ -108,24 -108,24 +97,24 @@@ typedef Value mapped_type ; ///< Type of value stored in the list typedef std::pair value_type ; ///< key/value pair stored in the list #else -- typedef typename options::key_type key_type; -- typedef typename options::value_type mapped_type; -- typedef typename options::pair_type value_type; ++ typedef typename maker::key_type key_type; ++ typedef typename maker::value_type mapped_type; ++ typedef typename maker::pair_type value_type; #endif -- typedef typename base_class::gc gc ; ///< Garbage collector used -- typedef typename base_class::back_off back_off ; ///< Back-off strategy used -- typedef typename options::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 options::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::gc gc; ///< Garbage collector used ++ 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 protected: //@cond -- typedef typename base_class::value_type node_type; -- typedef typename options::cxx_allocator cxx_allocator; -- typedef typename options::node_deallocator node_deallocator; -- typedef typename options::type_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 maker::intrusive_traits::compare intrusive_key_comparator; typedef typename base_class::atomic_node_ptr head_type; //@endcond @@@ -350,9 -350,9 +339,9 @@@ The function creates a node with \p key and default value, and then inserts the node created into the list. Preconditions: -- - The \ref key_type should be constructible from value of type \p K. -- In trivial case, \p K is equal to \ref key_type. -- - The \ref mapped_type should be default-constructible. ++ - The \p key_type should be constructible from value of type \p K. ++ In trivial case, \p K is equal to \p key_type. ++ - The \p mapped_type should be default-constructible. Returns \p true if inserting successful, \p false otherwise. */ @@@ -367,8 -367,8 +356,8 @@@ The function creates a node with \p key and value \p val, and then inserts the node created into the list. Preconditions: -- - The \ref key_type should be constructible from \p key of type \p K. -- - The \ref mapped_type should be constructible from \p val of type \p V. ++ - The \p key_type should be constructible from \p key of type \p K. ++ - The \p mapped_type should be constructible from \p val of type \p V. Returns \p true if inserting successful, \p false otherwise. */ @@@ -392,17 -392,17 +381,16 @@@ \endcode The argument \p item of user-defined functor \p func is the reference -- to the list's item inserted. item.second is a reference to item's value that may be changed. ++ to the item inserted. item.second is a reference to item's value that may be changed. User-defined functor \p func should guarantee that during changing item's value no any other changes could be made on this list's item by concurrent threads. -- The user-defined functor can be passed by reference using \p std::ref -- and it is called only if inserting is successful. ++ The user-defined functor is called only if inserting is successful. -- The key_type should be constructible from value of type \p K. ++ The \p key_type should be constructible from value of type \p K. The function allows to split creating of new item into two part: -- - create item from \p key; -- - insert new item into the list; ++ - create a new item from \p key; ++ - insert the new item into the list; - if inserting is successful, initialize the value of item by calling \p func functor This can be useful if complete initialization of object of \p mapped_type is heavyweight and @@@ -419,7 -419,7 +407,7 @@@ The operation performs inserting or changing data with lock-free manner. If the \p key not found in the list, then the new item created from \p key -- is inserted into the list (note that in this case the \ref key_type should be ++ is inserted into the list (note that in this case the \p key_type should be copy-constructible from type \p K). Otherwise, the functor \p func is called with item found. The functor \p Func may be a function with signature: @@@ -437,12 -437,12 +425,10 @@@ - \p bNew - \p true if the item has been inserted, \p false otherwise - \p item - item of the list -- The functor may change any fields of the \p item.second that is \ref mapped_type; ++ The functor may change any fields of the \p item.second of \p mapped_type; however, \p func must guarantee that during changing no any other modifications could be made on this item by concurrent threads. -- You may pass \p func argument by reference using \p std::ref -- Returns std::pair where \p first is true if operation is successfull, \p second is true if new item has been added or \p false if the item with \p key already is in the list. @@@ -453,8 -453,8 +439,11 @@@ return ensure_at( head(), key, f ); } -- /// Inserts data of type \ref mapped_type constructed with std::forward(args)... ++ /// Inserts a new node using move semantics /** ++ \p key_type field of new item is constructed from \p key argument, ++ \p mapped_type field is done from \p args. ++ Returns \p true if inserting successful, \p false otherwise. */ template @@@ -484,7 -484,7 +473,7 @@@ template bool erase_with( K const& key, Less pred ) { -- return erase_at( head(), key, typename options::template less_wrapper::type() ); ++ return erase_at( head(), key, typename maker::template less_wrapper::type() ); } /// Deletes \p key from the list @@@ -520,7 -520,7 +509,7 @@@ template bool erase_with( K const& key, Less pred, Func f ) { -- return erase_at( head(), key, typename options::template less_wrapper::type(), f ); ++ return erase_at( head(), key, typename maker::template less_wrapper::type(), f ); } /// Extracts the item from the list with specified \p key @@@ -569,7 -569,7 +558,7 @@@ template bool extract_with( guarded_ptr& dest, K const& key, Less pred ) { -- return extract_at( head(), dest.guard(), key, typename options::template less_wrapper::type() ); ++ return extract_at( head(), dest.guard(), key, typename maker::template less_wrapper::type() ); } /// Finds the key \p key @@@ -593,7 -593,7 +582,7 @@@ template bool find_with( Q const& key, Less pred ) { -- return find_at( head(), key, typename options::template less_wrapper::type() ); ++ return find_at( head(), key, typename maker::template less_wrapper::type() ); } /// Finds the key \p key and performs an action with it @@@ -632,7 -632,7 +621,7 @@@ template bool find_with( Q const& key, Less pred, Func f ) { -- return find_at( head(), key, typename options::template less_wrapper::type(), f ); ++ return find_at( head(), key, typename maker::template less_wrapper::type(), f ); } /// Finds the \p key and return the item found @@@ -683,7 -683,7 +672,7 @@@ template bool get_with( guarded_ptr& ptr, K const& key, Less pred ) { -- return get_at( head(), ptr.guard(), key, typename options::template less_wrapper::type() ); ++ return get_at( head(), ptr.guard(), key, typename maker::template less_wrapper::type() ); } /// Checks if the list is empty @@@ -694,11 -694,11 +683,11 @@@ /// Returns list's item count /** -- The value returned depends on opt::item_counter option. For atomicity::empty_item_counter, ++ The value returned depends on item counter provided by \p Traits. For \p atomicity::empty_item_counter, this function always returns 0. -- Warning: even if you use real item counter and it returns 0, this fact is not mean that the list -- is empty. To check list emptyness use \ref empty() method. ++ @note Even if you use real item counter and it returns 0, this fact is not mean that the list ++ is empty. To check list emptyness use \p empty() method. */ size_t size() const { @@@ -706,9 -706,9 +695,6 @@@ } /// Clears the list -- /** -- Post-condition: the list is empty -- */ void clear() { base_class::clear(); diff --cc cds/container/impl/michael_list.h index 1ea66117,1ea66117..d600a9e1 --- a/cds/container/impl/michael_list.h +++ b/cds/container/impl/michael_list.h @@@ -13,7 -13,7 +13,8 @@@ namespace cds { namespace container \anchor cds_nonintrusive_MichaelList_gc Usually, ordered single-linked list is used as a building block for the hash table implementation. -- The complexity of searching is O(N). ++ The complexity of searching is O(N), where \p N is the item count in the list, not in the ++ hash table. Source: - [2002] Maged Michael "High performance dynamic lock-free hash tables and list-based sets" @@@ -23,7 -23,7 +24,7 @@@ Template arguments: - \p GC - garbage collector used - \p T - type stored in the list. The type must be default- and copy-constructible. -- - \p Traits - type traits, default is michael_list::type_traits ++ - \p Traits - type traits, default is \p michael_list::traits Unlike standard container, this implementation does not divide type \p T into key and value part and may be used as a main building block for hash set algorithms. @@@ -44,8 -44,8 +45,8 @@@ } }; -- // Declare type_traits -- struct my_traits: public cds::container::michael_list::type_traits ++ // Declare traits ++ struct my_traits: public cds::container::michael_list::traits { typedef my_compare compare; }; @@@ -68,16 -68,16 +69,6 @@@ > option_based_list; \endcode -- Template argument list \p Options of cds::container::michael_list::make_traits metafunction are: -- - opt::compare - key comparison functor. No default functor is provided. -- If the option is not specified, the opt::less is used. -- - opt::less - specifies binary predicate used for key comparison. Default is \p std::less. -- - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::empty is used. -- - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter that is no item counting. -- - opt::allocator - the allocator used for creating and freeing list's item. Default is \ref CDS_DEFAULT_ALLOCATOR macro. -- - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default) -- or opt::v::sequential_consistent (sequentially consisnent memory model). -- \par Usage There are different specializations of this template for each garbage collecting schema used. You should include appropriate .h-file depending on GC you are using: @@@ -90,7 -90,7 +81,7 @@@ typename GC, typename T, #ifdef CDS_DOXYGEN_INVOKED -- typename Traits = michael_list::type_traits ++ typename Traits = michael_list::traits #else typename Traits #endif @@@ -103,25 -103,25 +94,27 @@@ #endif { //@cond -- typedef details::make_michael_list< GC, T, Traits > options; -- typedef typename options::type base_class; ++ typedef details::make_michael_list< GC, T, Traits > maker; ++ typedef typename maker::type base_class; //@endcond public: -- typedef T value_type ; ///< Type of value stored in the list -- typedef typename base_class::gc gc ; ///< Garbage collector used -- typedef typename base_class::back_off back_off ; ///< Back-off strategy used -- typedef typename options::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 options::key_comparator key_comparator ; ///< key comparison functor -- typedef typename base_class::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option ++ typedef T value_type; ///< Type of value stored in the list ++ typedef Traits traits; ///< List traits ++ ++ typedef typename base_class::gc gc; ///< Garbage collector used ++ 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 \p cds::opt::memory_model option protected: //@cond -- typedef typename base_class::value_type node_type; -- typedef typename options::cxx_allocator cxx_allocator; -- typedef typename options::node_deallocator node_deallocator; -- typedef typename options::type_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 maker::intrusive_traits::compare intrusive_key_comparator; typedef typename base_class::atomic_node_ptr head_type; //@endcond @@@ -167,7 -167,7 +160,7 @@@ free_node( pNode ); } }; -- typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr; ++ typedef std::unique_ptr< node_type, node_disposer > scoped_node_ptr; head_type& head() { @@@ -181,7 -181,7 +174,7 @@@ //@endcond protected: -- //@cond ++ //@cond template class iterator_type: protected base_class::template iterator_type { @@@ -326,7 -326,7 +319,7 @@@ The function creates a node with copy of \p val value and then inserts the node created into the list. -- The type \p Q should contain as minimum the complete key of the node. ++ The type \p Q should contain least the complete key of the node. The object of \ref value_type should be constructible from \p val of type \p Q. In trivial case, \p Q is equal to \ref value_type. @@@ -347,18 -347,18 +340,17 @@@ The argument \p itemValue of user-defined functor \p func is the reference to the list's item inserted. User-defined functor \p func should guarantee that during changing item's value no any other changes could be made on this list's item by concurrent threads. -- The user-defined functor can be passed by reference using \p std::ref -- and it is called only if the inserting is success. ++ The user-defined functor is called only if inserting is success. The type \p Q should contain the complete key of the node. -- The object of \ref value_type should be constructible from \p key of type \p Q. ++ The object of \p value_type should be constructible from \p key of type \p Q. The function allows to split creating of new item into two part: - create item from \p key with initializing key-fields only; - insert new item into the list; -- - if inserting is successful, initialize non-key fields of item by calling \p f functor ++ - if inserting is successful, initialize non-key fields of item by calling \p func functor -- This can be useful if complete initialization of object of \p value_type is heavyweight and ++ The method can be useful if complete initialization of object of \p value_type is heavyweight and it is preferable that the initialization should be completed only if inserting is successful. */ template @@@ -392,19 -392,19 +384,17 @@@ The functor may change non-key fields of the \p item; however, \p func must guarantee that during changing no any other modifications could be made on this item by concurrent threads. -- You may pass \p func argument by reference by \p std::ref -- Returns std::pair where \p first is true if operation is successfull, \p second is true if new item has been added or \p false if the item with \p key already is in the list. */ template -- std::pair ensure( Q const& key, Func f ) ++ std::pair ensure( Q const& key, Func func ) { -- return ensure_at( head(), key, f ); ++ return ensure_at( head(), key, func ); } -- /// Inserts data of type \ref value_type constructed with std::forward(args)... ++ /// Inserts data of type \p value_type constructed with std::forward(args)... /** Returns \p true if inserting successful, \p false otherwise. */ @@@ -416,9 -416,9 +406,9 @@@ /// Delete \p key from the list /** \anchor cds_nonintrusive_MichealList_hp_erase_val -- Since the key of MichaelList's item type \p T is not explicitly specified, -- template parameter \p Q defines the key type searching in the list. -- The list item comparator should be able to compare the type \p T of list item ++ Since the key of MichaelList's item type \p value_type is not explicitly specified, ++ template parameter \p Q sould contain the complete key to search in the list. ++ The list item comparator should be able to compare the type \p value_type and the type \p Q. Return \p true if key is found and deleted, \p false otherwise @@@ -439,7 -439,7 +429,7 @@@ template bool erase_with( Q const& key, Less pred ) { -- return erase_at( head(), key, typename options::template less_wrapper::type(), [](value_type const&){} ); ++ return erase_at( head(), key, typename maker::template less_wrapper::type(), [](value_type const&){} ); } /// Deletes \p key from the list @@@ -455,14 -455,14 +445,12 @@@ \endcode The functor may be passed by reference with boost:ref -- Since the key of MichaelList's item type \p T is not explicitly specified, -- template parameter \p Q defines the key type searching in the list. -- The list item comparator should be able to compare the type \p T of list item ++ Since the key of MichaelList's item type \p value_type is not explicitly specified, ++ template parameter \p Q should contain the complete key to search in the list. ++ The list item comparator should be able to compare the type \p value_type of list item and the type \p Q. Return \p true if key is found and deleted, \p false otherwise -- -- See also: \ref erase */ template bool erase( Q const& key, Func f ) @@@ -480,7 -480,7 +468,7 @@@ template bool erase_with( Q const& key, Less pred, Func f ) { -- return erase_at( head(), key, typename options::template less_wrapper::type(), f ); ++ return erase_at( head(), key, typename maker::template less_wrapper::type(), f ); } /// Extracts the item from the list with specified \p key @@@ -519,17 -519,17 +507,17 @@@ The function is an analog of \ref cds_nonintrusive_MichaelList_hp_extract "extract(guarded_ptr&, Q const&)" but \p pred predicate is used for key comparing. -- \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q ++ \p Less functor has the semantics like \p std::less but it should accept arguments of type \p value_type and \p Q in any order. \p pred must imply the same element order as the comparator used for building the list. */ template bool extract_with( guarded_ptr& dest, Q const& key, Less pred ) { -- return extract_at( head(), dest.guard(), key, typename options::template less_wrapper::type() ); ++ return extract_at( head(), dest.guard(), key, typename maker::template less_wrapper::type() ); } -- /// Find the key \p key ++ /// Finds \p key /** \anchor cds_nonintrusive_MichaelList_hp_find_val The function searches the item with key equal to \p key and returns \p true if it is found, and \p false otherwise @@@ -540,7 -540,7 +528,7 @@@ return find_at( head(), key, intrusive_key_comparator() ); } -- /// Finds the key \p val using \p pred predicate for searching ++ /// Finds \p key using \p pred predicate for searching /** The function is an analog of \ref cds_nonintrusive_MichaelList_hp_find_val "find(Q const&)" but \p pred is used for key comparing. @@@ -550,39 -550,39 +538,34 @@@ template bool find_with( Q const& key, Less pred ) { -- return find_at( head(), key, typename options::template less_wrapper::type() ); ++ return find_at( head(), key, typename maker::template less_wrapper::type() ); } -- /// Find the key \p val and perform an action with it ++ /// Finds \p key and perform an action with it /** \anchor cds_nonintrusive_MichaelList_hp_find_func -- The function searches an item with key equal to \p val and calls the functor \p f for the item found. ++ The function searches an item with key equal to \p key and calls the functor \p f for the item found. The interface of \p Func functor is: \code struct functor { -- void operator()( value_type& item, Q& val ); ++ void operator()( value_type& item, Q& key ); }; \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You may pass \p f argument by reference using \p std::ref ++ where \p item is the item found, \p key is the find function argument. The functor may change non-key fields of \p item. Note that the function is only guarantee that \p item cannot be deleted during functor is executing. The function does not serialize simultaneous access to the list \p item. If such access is possible you must provide your own synchronization schema to exclude unsafe item modifications. -- The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor -- may modify both arguments. -- -- The function returns \p true if \p val is found, \p false otherwise. ++ The function returns \p true if \p key is found, \p false otherwise. */ template -- bool find( Q& val, Func f ) ++ bool find( Q& key, Func f ) { -- return find_at( head(), val, intrusive_key_comparator(), f ); ++ return find_at( head(), key, intrusive_key_comparator(), f ); } -- /// Finds the key \p val using \p pred predicate for searching ++ /// Finds \p key using \p pred predicate for searching /** The function is an analog of \ref cds_nonintrusive_MichaelList_hp_find_func "find(Q&, Func)" but \p pred is used for key comparing. @@@ -590,56 -590,56 +573,17 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool find_with( Q& val, Less pred, Func f ) -- { -- return find_at( head(), val, typename options::template less_wrapper::type(), f ); -- } -- -- /// Find the key \p val and perform an action with it -- /** \anchor cds_nonintrusive_MichaelList_hp_find_cfunc -- The function searches an item with key equal to \p val and calls the functor \p f for the item found. -- The interface of \p Func functor is: -- \code -- struct functor { -- void operator()( value_type& item, Q const& val ); -- }; -- \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You may pass \p f argument by reference using \p std::ref -- -- The functor may change non-key fields of \p item. Note that the function is only guarantee -- that \p item cannot be deleted during functor is executing. -- The function does not serialize simultaneous access to the list \p item. If such access is -- possible you must provide your own synchronization schema to exclude unsafe item modifications. -- -- The function returns \p true if \p val is found, \p false otherwise. -- */ -- template -- bool find( Q const& val, Func f ) -- { -- return find_at( head(), val, intrusive_key_comparator(), f ); -- } -- -- /// Finds the key \p val using \p pred predicate for searching -- /** -- The function is an analog of \ref cds_nonintrusive_MichaelList_hp_find_cfunc "find(Q&, Func)" -- 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 -- bool find_with( Q const& val, Less pred, Func f ) ++ bool find_with( Q& key, Less pred, Func f ) { -- return find_at( head(), val, typename options::template less_wrapper::type(), f ); ++ return find_at( head(), key, typename maker::template less_wrapper::type(), f ); } -- /// Finds the key \p val and return the item found ++ /// Finds \p key and return the item found /** \anchor cds_nonintrusive_MichaelList_hp_get -- The function searches the item with key equal to \p val ++ The function searches the item with key equal to \p key and assigns the item found to guarded pointer \p ptr. -- The function returns \p true if \p val is found, and \p false otherwise. -- If \p val is not found the \p ptr parameter is not changed. ++ The function returns \p true if \p key is found, and \p false otherwise. ++ If \p key is not found the \p ptr parameter is not changed. @note Each \p guarded_ptr object uses one GC's guard which can be limited resource. @@@ -662,24 -662,24 +606,24 @@@ should accept a parameter of type \p Q that can be not the same as \p value_type. */ template -- bool get( guarded_ptr& ptr, Q const& val ) ++ bool get( guarded_ptr& ptr, Q const& key ) { -- return get_at( head(), ptr.guard(), val, intrusive_key_comparator() ); ++ return get_at( head(), ptr.guard(), key, intrusive_key_comparator() ); } -- /// Finds the key \p val and return the item found ++ /// Finds \p key and return the item found /** The function is an analog of \ref cds_nonintrusive_MichaelList_hp_get "get( guarded_ptr& ptr, Q const&)" but \p pred is used for comparing the keys. -- \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q ++ \p Less functor has the semantics like \p std::less but should accept arguments of type \p value_type and \p Q in any order. \p pred must imply the same element order as the comparator used for building the list. */ template -- bool get_with( guarded_ptr& ptr, Q const& val, Less pred ) ++ bool get_with( guarded_ptr& ptr, Q const& key, Less pred ) { -- return get_at( head(), ptr.guard(), val, typename options::template less_wrapper::type() ); ++ return get_at( head(), ptr.guard(), key, typename maker::template less_wrapper::type() ); } /// Check if the list is empty @@@ -690,11 -690,11 +634,11 @@@ /// Returns list's item count /** -- The value returned depends on opt::item_counter option. For atomics::empty_item_counter, ++ The value returned depends on item counter provided by \p Traits. For \p atomicity::empty_item_counter, this function always returns 0. -- Warning: even if you use real item counter and it returns 0, this fact is not mean that the list -- is empty. To check list emptyness use \ref empty() method. ++ @note Even if you use real item counter and it returns 0, this fact is not mean that the list ++ is empty. To check list emptyness use \p empty() method. */ size_t size() const { @@@ -702,9 -702,9 +646,6 @@@ } /// Clears the list -- /** -- Post-condition: the list is empty -- */ void clear() { base_class::clear(); diff --cc cds/container/michael_list_nogc.h index abae2284,abae2284..13d6a60f --- a/cds/container/michael_list_nogc.h +++ b/cds/container/michael_list_nogc.h @@@ -30,20 -30,20 +30,24 @@@ namespace cds { namespace container } // namespace details //@endcond -- /// Michael's lock-free ordered single-linked list (template specialization for gc::nogc) ++ /// Michael's lock-free ordered single-linked list (template specialization for \pgc::nogc) /** @ingroup cds_nonintrusive_list \anchor cds_nonintrusive_MichaelList_nogc -- This specialization is intended for so-called persistent usage when no item ++ This specialization is intended for so-called append-only usage when no item reclamation may be performed. The class does not support deleting of list item. Usually, ordered single-linked list is used as a building block for the hash table implementation. The complexity of searching is O(N). See \ref cds_nonintrusive_MichaelList_gc "MichaelList" for description of template parameters. -- -- The interface of the specialization is a little different. */ -- template ++ template class MichaelList: #ifdef CDS_DOXYGEN_INVOKED protected intrusive::MichaelList< gc::nogc, T, Traits > diff --cc cds/container/michael_list_rcu.h index fef238fb,fef238fb..740f0d86 --- a/cds/container/michael_list_rcu.h +++ b/cds/container/michael_list_rcu.h @@@ -26,7 -26,7 +26,7 @@@ namespace cds { namespace container Template arguments: - \p RCU - one of \ref cds_urcu_gc "RCU type" - \p T - type stored in the list. The type must be default- and copy-constructible. -- - \p Traits - type traits, default is michael_list::type_traits ++ - \p Traits - type traits, default is michael_list::traits The implementation does not divide type \p T into key and value part and may be used as a main building block for hash set containers. @@@ -53,8 -53,8 +53,8 @@@ } }; -- // Declare type_traits -- struct my_traits: public cds::container::michael_list::type_traits ++ // Declare traits ++ struct my_traits: public cds::container::michael_list::traits { typedef my_compare compare; }; @@@ -93,7 -93,7 +93,7 @@@ typename RCU, typename T, #ifdef CDS_DOXYGEN_INVOKED -- typename Traits = michael_list::type_traits ++ typename Traits = michael_list::traits #else typename Traits #endif @@@ -106,18 -106,18 +106,20 @@@ #endif { //@cond -- typedef details::make_michael_list< cds::urcu::gc, T, Traits > options; -- typedef typename options::type base_class; ++ typedef details::make_michael_list< cds::urcu::gc, T, Traits > maker; ++ typedef typename maker::type base_class; //@endcond public: -- typedef T value_type ; ///< Type of value stored in the list -- typedef typename base_class::gc gc ; ///< RCU schema used -- typedef typename base_class::back_off back_off ; ///< Back-off strategy used -- typedef typename options::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 options::key_comparator key_comparator ; ///< key comparison functor -- typedef typename base_class::memory_model memory_model ; ///< Memory ordering. See cds::opt::memory_model option ++ typedef cds::urcu::gc gc; ///< RCU ++ 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::rcu_check_deadlock rcu_check_deadlock ; ///< RCU deadlock checking policy typedef typename gc::scoped_lock rcu_lock ; ///< RCU scoped lock @@@ -125,16 -125,16 +127,16 @@@ protected: //@cond -- typedef typename base_class::value_type node_type; -- typedef typename options::cxx_allocator cxx_allocator; -- typedef typename options::node_deallocator node_deallocator; -- typedef typename options::type_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 maker::intrusive_traits::compare intrusive_key_comparator; typedef typename base_class::atomic_node_ptr head_type; //@endcond public: -- typedef cds::urcu::exempt_ptr< gc, node_type, value_type, typename options::type_traits::disposer > exempt_ptr; ///< pointer to extracted node ++ typedef cds::urcu::exempt_ptr< gc, node_type, value_type, typename maker::intrusive_traits::disposer > exempt_ptr; ///< pointer to extracted node private: //@cond @@@ -386,8 -386,8 +388,6 @@@ The functor may change non-key fields of the \p item; however, \p func must guarantee that during changing no any other modifications could be made on this item by concurrent threads. -- You may pass \p func argument by reference using \p std::ref -- The function makes RCU lock internally. Returns std::pair where \p first is true if operation is successfull, @@@ -400,7 -400,7 +400,7 @@@ return ensure_at( head(), key, f ); } -- /// Inserts data of type \ref value_type constructed with std::forward(args)... ++ /// Inserts data of type \ref value_type constructed from \p args /** Returns \p true if inserting successful, \p false otherwise. @@@ -414,10 -414,10 +414,10 @@@ /// Deletes \p key from the list /** \anchor cds_nonintrusive_MichealList_rcu_erase_val -- Since the key of MichaelList's item type \p T is not explicitly specified, ++ Since the key of MichaelList's item type \p value_type is not explicitly specified, template parameter \p Q defines the key type searching in the list. -- The list item comparator should be able to compare the type \p T of list item -- and the value \p key of type \p Q. ++ The list item comparator should be able to compare values of the type \p value_type ++ and \p Q in any order. RCU \p synchronize method can be called. RCU should not be locked. @@@ -439,7 -439,7 +439,7 @@@ template bool erase_with( Q const& key, Less pred ) { -- return erase_at( head(), key, typename options::template less_wrapper::type(), [](value_type const&){} ); ++ return erase_at( head(), key, typename maker::template less_wrapper::type(), [](value_type const&){} ); } /// Deletes \p key from the list @@@ -453,12 -453,12 +453,11 @@@ void operator()(const value_type& val) { ... } }; \endcode -- The functor may be passed by reference with boost:ref -- Since the key of MichaelList's item type \p T is not explicitly specified, ++ Since the key of MichaelList's item type \p value_type is not explicitly specified, template parameter \p Q defines the key type searching in the list. -- The list item comparator should be able to compare the type \p T of list item -- and the type \p Q. ++ The list item comparator should be able to compare the values of type \p value_type ++ and \p Q in any order. RCU \p synchronize method can be called. RCU should not be locked. @@@ -480,15 -480,15 +479,15 @@@ template bool erase_with( Q const& key, Less pred, Func f ) { -- return erase_at( head(), key, typename options::template less_wrapper::type(), f ); ++ return erase_at( head(), key, typename maker::template less_wrapper::type(), f ); } /// Extracts an item from the list /** @anchor cds_nonintrusive_MichaelList_rcu_extract -- The function searches an item with key equal to \p val in the list, ++ The function searches an item with key equal to \p key in the list, unlinks it from the list, and returns pointer to an item found in \p dest argument. -- If the item with the key equal to \p val is not found the function returns \p false. ++ If the item with the key equal to \p key is not found the function returns \p false. @note The function does NOT call RCU read-side lock or synchronization, and does NOT dispose the item found. It just excludes the item from the list @@@ -523,9 -523,9 +522,9 @@@ \endcode */ template -- bool extract( exempt_ptr& dest, Q const& val ) ++ bool extract( exempt_ptr& dest, Q const& key ) { -- dest = extract_at( head(), val, intrusive_key_comparator() ); ++ dest = extract_at( head(), key, intrusive_key_comparator() ); return !dest.empty(); } @@@ -538,9 -538,9 +537,9 @@@ \p pred must imply the same element order as \ref key_comparator. */ template -- bool extract_with( exempt_ptr& dest, Q const& val, Less pred ) ++ bool extract_with( exempt_ptr& dest, Q const& key, Less pred ) { -- dest = extract_at( head(), val, typename options::template less_wrapper::type() ); ++ dest = extract_at( head(), key, typename maker::template less_wrapper::type() ); return !dest.empty(); } @@@ -567,41 -567,41 +566,36 @@@ template bool find_with( Q const& key, Less pred ) const { -- return find_at( head(), key, typename options::template less_wrapper::type() ); ++ return find_at( head(), key, typename maker::template less_wrapper::type() ); } -- /// Finds the key \p val and performs an action with it ++ /// Finds the key \p key and performs an action with it /** \anchor cds_nonintrusive_MichaelList_rcu_find_func -- The function searches an item with key equal to \p val and calls the functor \p f for the item found. ++ The function searches an item with key equal to \p key and calls the functor \p f for the item found. The interface of \p Func functor is: \code struct functor { -- void operator()( value_type& item, Q& val ); ++ void operator()( value_type& item, Q& key ); }; \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You may pass \p f argument by reference using \p std::ref. ++ where \p item is the item found, \p key is the \p %find() function argument. The functor may change non-key fields of \p item. Note that the function is only guarantee that \p item cannot be deleted during functor is executing. The function does not serialize simultaneous access to the list \p item. If such access is possible you must provide your own synchronization schema to exclude unsafe item modifications. -- The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor -- may modify both arguments. -- The function makes RCU lock internally. The function returns \p true if \p val is found, \p false otherwise. */ template -- bool find( Q& val, Func f ) const ++ bool find( Q& key, Func f ) const { -- return find_at( head(), val, intrusive_key_comparator(), f ); ++ return find_at( head(), key, intrusive_key_comparator(), f ); } -- /// Finds the key \p val using \p pred predicate for searching ++ /// Finds the key \p key using \p pred predicate for searching /** The function is an analog of \ref cds_nonintrusive_MichaelList_rcu_find_func "find(Q&, Func)" but \p pred is used for key comparing. @@@ -609,56 -609,56 +603,15 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool find_with( Q& val, Less pred, Func f ) const -- { -- return find_at( head(), val, typename options::template less_wrapper::type(), f ); -- } -- -- /// Finds the key \p val and performs an action with it -- /** \anchor cds_nonintrusive_MichaelList_rcu_find_cfunc -- The function searches an item with key equal to \p val and calls the functor \p f for the item found. -- The interface of \p Func functor is: -- \code -- struct functor { -- void operator()( value_type& item, Q const& val ); -- }; -- \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You may pass \p f argument by reference using \p std::ref. -- -- The functor may change non-key fields of \p item. Note that the function is only guarantee -- that \p item cannot be deleted during functor is executing. -- The function does not serialize simultaneous access to the list \p item. If such access is -- possible you must provide your own synchronization schema to exclude unsafe item modifications. -- -- The function makes RCU lock internally. -- -- The function returns \p true if \p val is found, \p false otherwise. -- */ -- template -- bool find( Q const& val, Func f ) const -- { -- return find_at( head(), val, intrusive_key_comparator(), f ); -- } -- -- /// Finds the key \p val using \p pred predicate for searching -- /** -- The function is an analog of \ref cds_nonintrusive_MichaelList_rcu_find_cfunc "find(Q&, Func)" -- 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 -- bool find_with( Q const& val, Less pred, Func f ) const ++ bool find_with( Q& key, Less pred, Func f ) const { -- return find_at( head(), val, typename options::template less_wrapper::type(), f ); ++ return find_at( head(), key, typename maker::template less_wrapper::type(), f ); } -- /// Finds the key \p val and return the item found ++ /// Finds the key \p key and return the item found /** \anchor cds_nonintrusive_MichaelList_rcu_get -- The function searches the item with key equal to \p val and returns the pointer to item found. -- If \p val is not found it returns \p nullptr. ++ The function searches the item with key equal to \p key and returns the pointer to item found. ++ If \p key is not found it returns \p nullptr. Note the compare functor should accept a parameter of type \p Q that can be not the same as \p value_type. @@@ -683,12 -683,12 +636,12 @@@ \endcode */ template -- value_type * get( Q const& val ) const ++ value_type * get( Q const& key ) const { -- return get_at( head(), val, intrusive_key_comparator()); ++ return get_at( head(), key, intrusive_key_comparator()); } -- /// Finds the key \p val and return the item found ++ /// Finds \p key and return the item found /** The function is an analog of \ref cds_nonintrusive_MichaelList_rcu_get "get(Q const&)" but \p pred is used for comparing the keys. @@@ -698,9 -698,9 +651,9 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- value_type * get_with( Q const& val, Less pred ) const ++ value_type * get_with( Q const& key, Less pred ) const { -- return get_at( head(), val, typename options::template less_wrapper::type()); ++ return get_at( head(), key, typename maker::template less_wrapper::type()); } /// Checks if the list is empty @@@ -711,11 -711,11 +664,11 @@@ /// Returns list's item count /** -- The value returned depends on opt::item_counter option. For atomics::empty_item_counter, ++ The value returned depends on item counter provided by \p Traits. For \p atomicity::empty_item_counter, this function always returns 0. -- Warning: even if you use a real item counter and it returns 0, this fact is not mean that the list -- is empty. To check list emptyness use \ref empty() method. ++ @note Even if you use real item counter and it returns 0, this fact does not mean that the list ++ is empty. To check list emptyness use \p empty() method. */ size_t size() const { @@@ -723,9 -723,9 +676,6 @@@ } /// Clears the list -- /** -- Post-condition: the list is empty -- */ void clear() { base_class::clear(); diff --cc cds/intrusive/details/michael_list_base.h index bd556f3a,bd556f3a..89f57198 --- a/cds/intrusive/details/michael_list_base.h +++ b/cds/intrusive/details/michael_list_base.h @@@ -4,12 -4,12 +4,10 @@@ #define __CDS_INTRUSIVE_DETAILS_MICHAEL_LIST_BASE_H #include --#include // ref #include #include #include #include --#include #include namespace cds { namespace intrusive { @@@ -115,7 -115,7 +113,7 @@@ //@endcond }; -- /// Check link ++ /// Checks link template struct link_checker { @@@ -169,12 -169,12 +167,12 @@@ //@endcond }; -- /// Type traits for MichaelList class -- struct type_traits ++ /// MichaelList traits ++ struct traits { /// Hook used /** -- Possible values are: michael_list::base_hook, michael_list::member_hook, michael_list::traits_hook. ++ Possible values are: \p michael_list::base_hook, \p michael_list::member_hook, \p michael_list::traits_hook. */ typedef base_hook<> hook; @@@ -184,54 -184,54 +182,59 @@@ */ typedef opt::none compare; -- /// specifies binary predicate used for key compare. ++ /// Specifies binary predicate used for key compare. /** Default is \p std::less. */ typedef opt::none less; -- /// back-off strategy used -- /** -- If the option is not specified, the cds::backoff::Default is used. -- */ ++ /// Back-off strategy typedef cds::backoff::Default back_off; -- /// Disposer -- /** -- the functor used for dispose removed items. Default is opt::v::empty_disposer. -- */ ++ /// Disposer for removing items typedef opt::v::empty_disposer disposer; -- /// Item counter -- /** -- The type for item counting feature. -- Default is no item counter (\ref atomicity::empty_item_counter) -- */ ++ /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting typedef atomicity::empty_item_counter item_counter; /// Link fields checking feature /** -- Default is \ref opt::debug_check_link ++ Default is \p opt::debug_check_link */ static const opt::link_check_type link_checker = opt::debug_check_link; /// C++ memory ordering model -- /** -- List of available memory ordering see opt::memory_model ++ /** ++ Can be \p opt::v::relaxed_ordering (relaxed memory model, the default) ++ or \p opt::v::sequential_consistent (sequentially consisnent memory model). */ typedef opt::v::relaxed_ordering memory_model; /// RCU deadlock checking policy (only for \ref cds_intrusive_MichaelList_rcu "RCU-based MichaelList") /** -- List of available options see opt::rcu_check_deadlock ++ List of available policy see \p opt::rcu_check_deadlock */ typedef opt::v::rcu_throw_deadlock rcu_check_deadlock; }; -- /// Metafunction converting option list to traits ++ /// Metafunction converting option list to \p michael_list::traits /** -- This is a wrapper for cds::opt::make_options< type_traits, Options...> -- \p Options list see \ref MichaelList. ++ Supported \p Options are: ++ - \p opt::hook - hook used. Possible values are: \p michael_list::base_hook, \p michael_list::member_hook, \p michael_list::traits_hook. ++ If the option is not specified, \p %michael_list::base_hook<> and \p gc::HP is used. ++ - \p opt::compare - key comparison functor. No default functor is provided. ++ If the option is not specified, the \p opt::less is used. ++ - \p opt::less - specifies binary predicate used for key comparison. Default is \p std::less. ++ - \p opt::back_off - back-off strategy used. If the option is not specified, the \p cds::backoff::Default is used. ++ - \p opt::disposer - the functor used for disposing removed items. Default is \p opt::v::empty_disposer. Due the nature ++ of GC schema the disposer may be called asynchronously. ++ - \p opt::link_checker - the type of node's link fields checking. Default is \p opt::debug_check_link ++ - \p opt::item_counter - the type of item counting feature. Default is disabled (\p atomicity::empty_item_counter). ++ To enable item counting use \p atomicity::item_counter. ++ - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default) ++ or \p opt::v::sequential_consistent (sequentially consisnent memory model). ++ - \p opt::rcu_check_deadlock - a deadlock checking policy for \ref cds_intrusive_MichaelList_rcu "RCU-based MichaelList" ++ Default is \p opt::v::rcu_throw_deadlock */ template struct make_traits { @@@ -239,10 -239,10 +242,9 @@@ typedef implementation_defined type ; ///< Metafunction result # else typedef typename cds::opt::make_options< -- typename cds::opt::find_type_traits< type_traits, Options... >::type ++ typename cds::opt::find_type_traits< traits, Options... >::type ,Options... >::type type; -- //typedef typename cds::opt::make_options< type_traits, Options...>::type type ; ///< Result of metafunction # endif }; @@@ -250,7 -250,7 +252,7 @@@ //@cond // Forward declaration -- template < class GC, typename T, class Traits = michael_list::type_traits > ++ template < class GC, typename T, class Traits = michael_list::traits > class MichaelList; //@endcond diff --cc cds/intrusive/impl/michael_list.h index 7bc965e0,7bc965e0..f39b8a8c --- a/cds/intrusive/impl/michael_list.h +++ b/cds/intrusive/impl/michael_list.h @@@ -5,6 -5,6 +5,7 @@@ #include #include ++#include namespace cds { namespace intrusive { @@@ -19,71 -19,71 +20,53 @@@ - [2002] Maged Michael "High performance dynamic lock-free hash tables and list-based sets" Template arguments: -- - \p GC - Garbage collector used. Note the \p GC must be the same as the GC used for item type \p T (see michael_list::node). ++ - \p GC - Garbage collector used. Note the \p GC must be the same as the GC used for item type \p T (see \p michael_list::node). - \p T - type to be stored in the list. The type must be based on michael_list::node (for michael_list::base_hook) or it must have a member of type michael_list::node (for michael_list::member_hook). -- - \p Traits - type traits. See michael_list::type_traits for explanation. -- -- It is possible to declare option-based list with cds::intrusive::michael_list::make_traits metafunction istead of \p Traits template -- argument. -- -- Template argument list \p Options of cds::intrusive::michael_list::make_traits metafunction are: -- - opt::hook - hook used. Possible values are: michael_list::base_hook, michael_list::member_hook, michael_list::traits_hook. -- If the option is not specified, michael_list::base_hook<> and gc::HP is used. -- - opt::compare - key comparison functor. No default functor is provided. -- If the option is not specified, the opt::less is used. -- - opt::less - specifies binary predicate used for key comparison. Default is \p std::less. -- - opt::back_off - back-off strategy used. If the option is not specified, the cds::backoff::Default is used. -- - opt::disposer - the functor used for dispose removed items. Default is opt::v::empty_disposer. Due the nature -- of GC schema the disposer may be called asynchronously. -- - opt::link_checker - the type of node's link fields checking. Default is \ref opt::debug_check_link -- - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter that is no item counting. -- - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default) -- or opt::v::sequential_consistent (sequentially consisnent memory model). -- -- For example, the following traits-based declaration of gc::HP Michael's list -- \code -- #include -- // Declare item stored in your list -- struct item: public cds::intrusive::michael_list::node< cds::gc::HP > -- { -- int nKey; -- // .... other data -- }; -- -- // Declare comparator for the item -- struct my_compare { -- int operator()( item const& i1, item const& i2 ) const ++ - \p Traits - type traits, default is \p michael_list::traits. It is possible to declare option-based ++ list with \p cds::intrusive::michael_list::make_traits metafunction: ++ For example, the following traits-based declaration of \p gc::HP Michael's list ++ \code ++ #include ++ // Declare item stored in your list ++ struct item: public cds::intrusive::michael_list::node< cds::gc::HP > { -- return i1.nKey - i2.nKey; -- } -- }; ++ int nKey; ++ // .... other data ++ }; -- // Declare type_traits -- struct my_traits: public cds::intrusive::michael_list::type_traits -- { -- typedef cds::intrusive::michael_list::base_hook< cds::opt::gc< cds::gc::HP > > hook; -- typedef my_compare compare; -- }; ++ // Declare comparator for the item ++ struct my_compare { ++ int operator()( item const& i1, item const& i2 ) const ++ { ++ return i1.nKey - i2.nKey; ++ } ++ }; -- // Declare traits-based list -- typedef cds::intrusive::MichaelList< cds::gc::HP, item, my_traits > traits_based_list; -- \endcode ++ // Declare traits ++ struct my_traits: public cds::intrusive::michael_list::traits ++ { ++ typedef cds::intrusive::michael_list::base_hook< cds::opt::gc< cds::gc::HP > > hook; ++ typedef my_compare compare; ++ }; -- is equivalent for the following option-based list -- \code -- #include ++ // Declare traits-based list ++ typedef cds::intrusive::MichaelList< cds::gc::HP, item, my_traits > traits_based_list; ++ \endcode ++ is equivalent for the following option-based list ++ \code ++ #include -- // item struct and my_compare are the same ++ // item struct and my_compare are the same -- // Declare option-based list -- typedef cds::intrusive::MichaelList< cds::gc::HP, item, -- typename cds::intrusive::michael_list::make_traits< -- cds::intrusive::opt::hook< cds::intrusive::michael_list::base_hook< cds::opt::gc< cds::gc::HP > > > // hook option -- ,cds::intrusive::opt::compare< my_compare > // item comparator option -- >::type -- > option_based_list; -- \endcode ++ // Declare option-based list ++ typedef cds::intrusive::MichaelList< cds::gc::HP, item, ++ typename cds::intrusive::michael_list::make_traits< ++ cds::intrusive::opt::hook< cds::intrusive::michael_list::base_hook< cds::opt::gc< cds::gc::HP > > > // hook option ++ ,cds::intrusive::opt::compare< my_compare > // item comparator option ++ >::type ++ > option_based_list; ++ \endcode \par Usage There are different specializations of this template for each garbage collecting schema used. @@@ -95,10 -95,10 +78,10 @@@ See \ref cds_intrusive_MichaelList_nogc "non-GC MichaelList" Then, you should incorporate michael_list::node into your struct \p T and provide -- appropriate michael_list::type_traits::hook in your \p Traits template parameters. Usually, for \p Traits you -- define a struct based on michael_list::type_traits. ++ appropriate \p michael_list::traits::hook in your \p Traits template parameters. Usually, for \p Traits you ++ define a struct based on \p michael_list::traits. -- Example for gc::PTB and base hook: ++ Example for \p gc::PTB and base hook: \code // Include GC-related Michael's list specialization #include @@@ -132,8 -132,8 +115,8 @@@ }; -- // Declare type_traits -- struct my_traits: public cds::intrusive::michael_list::type_traits ++ // Declare traits ++ struct my_traits: public cds::intrusive::michael_list::traits { typedef cds::intrusive::michael_list::base_hook< cds::opt::gc< cds::gc::PTB > > hook; typedef my_data_cmp compare; @@@ -170,7 -170,7 +153,7 @@@ class GC ,typename T #ifdef CDS_DOXYGEN_INVOKED -- ,class Traits = michael_list::type_traits ++ ,class Traits = michael_list::traits #else ,class Traits #endif @@@ -178,49 -178,49 +161,49 @@@ class MichaelList { public: -- typedef T value_type ; ///< type of value stored in the list -- typedef Traits options ; ///< Traits template parameter ++ typedef T value_type; ///< type of value stored in the list ++ typedef Traits traits; ///< Traits template parameter -- typedef typename options::hook hook ; ///< hook type -- typedef typename hook::node_type node_type ; ///< node type ++ typedef typename traits::hook hook; ///< hook type ++ typedef typename hook::node_type node_type; ///< node type # ifdef CDS_DOXYGEN_INVOKED typedef implementation_defined key_comparator ; ///< key comparison functor based on opt::compare and opt::less option setter. # else -- typedef typename opt::details::make_comparator< value_type, options >::type key_comparator; ++ typedef typename opt::details::make_comparator< value_type, traits >::type key_comparator; # endif -- typedef typename options::disposer disposer ; ///< disposer used ++ typedef typename traits::disposer disposer; ///< disposer used typedef typename get_node_traits< value_type, node_type, hook>::type node_traits ; ///< node traits -- typedef typename michael_list::get_link_checker< node_type, options::link_checker >::type link_checker ; ///< link checker ++ typedef typename michael_list::get_link_checker< node_type, traits::link_checker >::type link_checker; ///< link checker typedef GC gc ; ///< Garbage collector -- typedef typename options::back_off back_off ; ///< back-off strategy -- typedef typename options::item_counter item_counter ; ///< Item counting policy used -- typedef typename options::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option ++ typedef typename traits::back_off back_off; ///< back-off strategy ++ typedef typename traits::item_counter item_counter; ///< Item counting policy used ++ typedef typename traits::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option typedef cds::gc::guarded_ptr< gc, value_type > guarded_ptr; ///< Guarded pointer //@cond -- // Rebind options (split-list support) ++ // Rebind traits (split-list support) template -- struct rebind_options { ++ struct rebind_traits { typedef MichaelList< gc , value_type -- , typename cds::opt::make_options< options, Options...>::type ++ , typename cds::opt::make_options< traits, Options...>::type > type; }; //@endcond protected: -- typedef typename node_type::atomic_marked_ptr atomic_node_ptr ; ///< Atomic node pointer -- typedef typename node_type::marked_ptr marked_node_ptr ; ///< Node marked pointer ++ typedef typename node_type::atomic_marked_ptr atomic_node_ptr; ///< Atomic node pointer ++ typedef typename node_type::marked_ptr marked_node_ptr; ///< Node marked pointer -- typedef atomic_node_ptr auxiliary_head ; ///< Auxiliary head type (for split-list support) ++ typedef atomic_node_ptr auxiliary_head; ///< Auxiliary head type (for split-list support) -- atomic_node_ptr m_pHead ; ///< Head pointer -- item_counter m_ItemCounter ; ///< Item counter ++ atomic_node_ptr m_pHead; ///< Head pointer ++ item_counter m_ItemCounter; ///< Item counter //@cond /// Position pointer for item search @@@ -245,18 -245,18 +228,17 @@@ disposer()( p ); } }; -- //@endcond protected: //@cond -- void retire_node( node_type * pNode ) ++ static void retire_node( node_type * pNode ) { assert( pNode != nullptr ); gc::template retire( node_traits::to_value_ptr( *pNode ) ); } -- bool link_node( node_type * pNode, position& pos ) ++ static bool link_node( node_type * pNode, position& pos ) { assert( pNode != nullptr ); link_checker::is_empty( pNode ); @@@ -266,7 -266,7 +248,7 @@@ return pos.pPrev->compare_exchange_strong( cur, marked_node_ptr(pNode), memory_model::memory_order_release, atomics::memory_order_relaxed ); } -- bool unlink_node( position& pos ) ++ static bool unlink_node( position& pos ) { assert( pos.pPrev != nullptr ); assert( pos.pCur != nullptr ); @@@ -403,11 -403,11 +385,11 @@@ The forward iterator for Michael's list has some features: - it has no post-increment operator - to protect the value, the iterator contains a GC-specific guard + another guard is required locally for increment operator. -- For some GC (gc::HP, gc::HRC), a guard is limited resource per thread, so an exception (or assertion) "no free guard" -- may be thrown if a limit of guard count per thread is exceeded. -- - The iterator cannot be moved across thread boundary since it contains GC's guard that is thread-private GC data. -- - Iterator ensures thread-safety even if you delete the item that iterator points to. However, in case of concurrent -- deleting operations it is no guarantee that you iterate all item in the list. ++ For some GC (like as \p gc::HP), a guard is a limited resource per thread, so an exception (or assertion) "no free guard" ++ may be thrown if the limit of guard count per thread is exceeded. ++ - The iterator cannot be moved across thread boundary since it contains thread-private GC's guard. ++ - Iterator ensures thread-safety even if you delete the item the iterator points to. However, in case of concurrent ++ deleting operations there is no guarantee that you iterate all item in the list. Therefore, the use of iterators in concurrent environment is not good idea. Use the iterator on the concurrent container for debug purpose only. @@@ -509,10 -509,10 +491,10 @@@ /// Inserts new node /** -- The function inserts \p val in the list if the list does not contain ++ The function inserts \p val into the list if the list does not contain an item with key equal to \p val. -- Returns \p true if \p val is linked into the list, \p false otherwise. ++ Returns \p true if \p val has been linked to the list, \p false otherwise. */ bool insert( value_type& val ) { @@@ -534,8 -534,8 +516,7 @@@ \endcode where \p val is the item inserted. User-defined functor \p f should guarantee that during changing \p val no any other changes could be made on this list's item by concurrent threads. -- The user-defined functor is called only if the inserting is success and may be passed by reference -- using \p std::ref ++ The user-defined functor is called only if the inserting is success. */ template bool insert( value_type& val, Func f ) @@@ -543,11 -543,11 +524,11 @@@ return insert_at( m_pHead, val, f ); } -- /// Ensures that the \p item exists in the list ++ /// Ensures that the \p val exists in the list /** The operation performs inserting or changing data with lock-free manner. -- If the item \p val not found in the list, then \p val is inserted into the list. ++ If the item \p val is not found in the list, then \p val is inserted. Otherwise, the functor \p func is called with item found. The functor signature is: \code @@@ -563,8 -563,8 +544,6 @@@ The functor may change non-key fields of the \p item; however, \p func must guarantee that during changing no any other modifications could be made on this item by concurrent threads. -- You may pass \p func argument by reference using \p std::ref. -- Returns std::pair where \p first is \p true if operation is successfull, \p second is \p true if new item has been added or \p false if the item with \p key already is in the list. @@@ -577,12 -577,12 +556,12 @@@ /// Unlinks the item \p val from the list /** -- The function searches the item \p val in the list and unlink it from the list ++ The function searches the item \p val in the list and unlinks it from the list if it is found and it is equal to \p val. -- Difference between \ref erase and \p unlink functions: \p erase finds a key -- and deletes the item found. \p unlink finds an item by key and deletes it -- only if \p val is an item of that list, i.e. the pointer to item found ++ Difference between \p erase() and \p %unlink(): \p %erase() finds a key ++ and deletes the item found. \p %unlink() finds an item by key and deletes it ++ only if \p val is an item of the list, i.e. the pointer to item found is equal to &val . The function returns \p true if success and \p false otherwise. @@@ -594,14 -594,14 +573,14 @@@ /// Deletes the item from the list /** \anchor cds_intrusive_MichaelList_hp_erase_val -- The function searches an item with key equal to \p val in the list, ++ The function searches an item with key equal to \p key in the list, unlinks it from the list, and returns \p true. -- If the item with the key equal to \p val is not found the function return \p false. ++ If \p key is not found the function return \p false. */ template -- bool erase( Q const& val ) ++ bool erase( Q const& key ) { -- return erase_at( m_pHead, val, key_comparator() ); ++ return erase_at( m_pHead, key, key_comparator() ); } /// Deletes the item from the list using \p pred predicate for searching @@@ -612,14 -612,14 +591,14 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool erase_with( Q const& val, Less pred ) ++ bool erase_with( Q const& key, Less pred ) { -- return erase_at( m_pHead, val, cds::opt::details::make_comparator_from_less()); ++ return erase_at( m_pHead, key, cds::opt::details::make_comparator_from_less()); } /// Deletes the item from the list /** \anchor cds_intrusive_MichaelList_hp_erase_func -- The function searches an item with key equal to \p val in the list, ++ The function searches an item with key equal to \p key in the list, call \p func functor with item found, unlinks it from the list, and returns \p true. The \p Func interface is \code @@@ -627,14 -627,14 +606,12 @@@ void operator()( value_type const& item ); }; \endcode -- The functor may be passed by reference using boost:ref -- -- If the item with the key equal to \p val is not found the function return \p false. ++ If \p key is not found the function return \p false, \p func is not called. */ template -- bool erase( Q const& val, Func func ) ++ bool erase( Q const& key, Func func ) { -- return erase_at( m_pHead, val, key_comparator(), func ); ++ return erase_at( m_pHead, key, key_comparator(), func ); } /// Deletes the item from the list using \p pred predicate for searching @@@ -645,9 -645,9 +622,9 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool erase_with( Q const& val, Less pred, Func f ) ++ bool erase_with( Q const& key, Less pred, Func f ) { -- return erase_at( m_pHead, val, cds::opt::details::make_comparator_from_less(), f ); ++ return erase_at( m_pHead, key, cds::opt::details::make_comparator_from_less(), f ); } /// Extracts the item from the list with specified \p key @@@ -698,36 -698,36 +675,34 @@@ return extract_at( m_pHead, dest.guard(), key, cds::opt::details::make_comparator_from_less() ); } -- /// Finds the key \p val ++ /// Finds \p key in the list /** \anchor cds_intrusive_MichaelList_hp_find_func -- The function searches the item with key equal to \p val and calls the functor \p f for item found. ++ The function searches the item with key equal to \p key and calls the functor \p f for item found. The interface of \p Func functor is: \code struct functor { -- void operator()( value_type& item, Q& val ); ++ void operator()( value_type& item, Q& key ); }; \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You may pass \p f argument by reference using \p std::ref. ++ where \p item is the item found, \p key is the find function argument. The functor may change non-key fields of \p item. Note that the function is only guarantee that \p item cannot be disposed during functor is executing. -- The function does not serialize simultaneous access to the list \p item. If such access is -- possible you must provide your own synchronization schema to exclude unsafe item modifications. ++ The function does not serialize simultaneous access to the \p item. If such access is ++ possible you must provide your own synchronization schema to keep out unsafe item modifications. -- The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor ++ The \p key argument is non-const since it can be used as \p f functor destination i.e., the functor may modify both arguments. The function returns \p true if \p val is found, \p false otherwise. */ template -- bool find( Q& val, Func f ) ++ bool find( Q& key, Func f ) { -- return find_at( m_pHead, val, key_comparator(), f ); ++ return find_at( m_pHead, key, key_comparator(), f ); } -- /// Finds the key \p val using \p pred predicate for searching ++ /// Finds the \p key using \p pred predicate for searching /** The function is an analog of \ref cds_intrusive_MichaelList_hp_find_func "find(Q&, Func)" but \p pred is used for key comparing. @@@ -735,59 -735,59 +710,20 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool find_with( Q& val, Less pred, Func f ) -- { -- return find_at( m_pHead, val, cds::opt::details::make_comparator_from_less(), f ); -- } -- -- /// Finds the key \p val -- /** \anchor cds_intrusive_MichaelList_hp_find_cfunc -- The function searches the item with key equal to \p val and calls the functor \p f for item found. -- The interface of \p Func functor is: -- \code -- struct functor { -- void operator()( value_type& item, Q const& val ); -- }; -- \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You may pass \p f argument by reference using \p std::ref. -- -- The functor may change non-key fields of \p item. Note that the function is only guarantee -- that \p item cannot be disposed during functor is executing. -- The function does not serialize simultaneous access to the list \p item. If such access is -- possible you must provide your own synchronization schema to exclude unsafe item modifications. -- -- The function returns \p true if \p val is found, \p false otherwise. -- */ -- template -- bool find( Q const& val, Func f ) -- { -- return find_at( m_pHead, val, key_comparator(), f ); -- } -- -- /// Finds the key \p val using \p pred predicate for searching -- /** -- The function is an analog of \ref cds_intrusive_MichaelList_hp_find_cfunc "find(Q const&, Func)" -- 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 -- bool find_with( Q const& val, Less pred, Func f ) ++ bool find_with( Q& key, Less pred, Func f ) { -- return find_at( m_pHead, val, cds::opt::details::make_comparator_from_less(), f ); ++ return find_at( m_pHead, key, cds::opt::details::make_comparator_from_less(), f ); } -- /// Finds the key \p val ++ /// Finds the \p key /** \anchor cds_intrusive_MichaelList_hp_find_val -- The function searches the item with key equal to \p val ++ The function searches the item with key equal to \p key and returns \p true if it is found, and \p false otherwise */ template -- bool find( Q const & val ) ++ bool find( Q const& key ) { -- return find_at( m_pHead, val, key_comparator() ); ++ return find_at( m_pHead, key, key_comparator() ); } /// Finds the key \p val using \p pred predicate for searching @@@ -798,17 -798,17 +734,17 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool find_with( Q const& val, Less pred ) ++ bool find_with( Q const& key, Less pred ) { -- return find_at( m_pHead, val, cds::opt::details::make_comparator_from_less() ); ++ return find_at( m_pHead, key, cds::opt::details::make_comparator_from_less() ); } -- /// Finds the key \p val and return the item found ++ /// Finds the \p key and return the item found /** \anchor cds_intrusive_MichaelList_hp_get -- The function searches the item with key equal to \p val ++ The function searches the item with key equal to \p key and assigns the item found to guarded pointer \p ptr. -- The function returns \p true if \p val is found, and \p false otherwise. -- If \p val is not found the \p ptr parameter is not changed. ++ The function returns \p true if \p key is found, and \p false otherwise. ++ If \p key is not found the \p ptr parameter is not changed. The \ref disposer specified in \p Traits class template parameter is called by garbage collector \p GC automatically when returned \ref guarded_ptr object @@@ -834,12 -834,12 +770,12 @@@ should accept a parameter of type \p Q that can be not the same as \p value_type. */ template -- bool get( guarded_ptr& ptr, Q const& val ) ++ bool get( guarded_ptr& ptr, Q const& key ) { -- return get_at( m_pHead, ptr.guard(), val, key_comparator() ); ++ return get_at( m_pHead, ptr.guard(), key, key_comparator() ); } -- /// Finds the key \p val and return the item found ++ /// Finds the \p key and return the item found /** The function is an analog of \ref cds_intrusive_MichaelList_hp_get "get( guarded_ptr& ptr, Q const&)" but \p pred is used for comparing the keys. @@@ -849,9 -849,9 +785,9 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool get_with( guarded_ptr& ptr, Q const& val, Less pred ) ++ bool get_with( guarded_ptr& ptr, Q const& key, Less pred ) { -- return get_at( m_pHead, ptr.guard(), val, cds::opt::details::make_comparator_from_less() ); ++ return get_at( m_pHead, ptr.guard(), key, cds::opt::details::make_comparator_from_less() ); } /// Clears the list @@@ -875,7 -875,7 +811,7 @@@ } } -- /// Checks if the list is empty ++ /// Checks whether the list is empty bool empty() const { return m_pHead.load( memory_model::memory_order_relaxed ).all() == nullptr; @@@ -883,11 -883,11 +819,11 @@@ /// Returns list's item count /** -- The value returned depends on opt::item_counter option. For atomicity::empty_item_counter, ++ The value returned depends on item counter provided by \p Traits. For \p atomicity::empty_item_counter, this function always returns 0. -- Warning: even if you use real item counter and it returns 0, this fact is not mean that the list -- is empty. To check list emptyness use \ref empty() method. ++ @note Even if you use real item counter and it returns 0, this fact does not mean that the list ++ is empty. To check list emptyness use \p empty() method. */ size_t size() const { diff --cc cds/intrusive/michael_list_nogc.h index 89a5ae6b,89a5ae6b..96ae276e --- a/cds/intrusive/michael_list_nogc.h +++ b/cds/intrusive/michael_list_nogc.h @@@ -5,6 -5,6 +5,8 @@@ #include #include ++#include ++ namespace cds { namespace intrusive { @@@ -28,53 -28,53 +30,56 @@@ : m_pNext( nullptr ) {} }; -- } // namespace michael_list /// Michael's lock-free ordered single-linked list (template specialization for gc::nogc) /** @ingroup cds_intrusive_list \anchor cds_intrusive_MichaelList_nogc -- This specialization is intended for so-called persistent usage when no item -- reclamation may be performed. The class does not support deleting of item. ++ This specialization is intended for so-called append-only usage when no item ++ reclamation may be performed. The class does not support item removal. See \ref cds_intrusive_MichaelList_hp "MichaelList" for description of template parameters. -- -- The interface of the specialization is a slightly different. */ -- template < typename T, class Traits > ++ template < typename T, ++#ifdef CDS_DOXYGEN_INVOKED ++ class Traits = michael_list::traits ++#else ++ class Traits ++#endif ++ > class MichaelList { public: -- typedef T value_type ; ///< type of value stored in the queue -- typedef Traits options ; ///< Traits template parameter ++ typedef gc::nogc gc; ///< Garbage collector ++ typedef T value_type; ///< type of value to be stored in the queue ++ typedef Traits traits; ///< List traits -- typedef typename options::hook hook ; ///< hook type -- typedef typename hook::node_type node_type ; ///< node type ++ typedef typename traits::hook hook; ///< hook type ++ typedef typename hook::node_type node_type; ///< node type # ifdef CDS_DOXYGEN_INVOKED typedef implementation_defined key_comparator ; ///< key comparison functor based on opt::compare and opt::less option setter. # else -- typedef typename opt::details::make_comparator< value_type, options >::type key_comparator; ++ typedef typename opt::details::make_comparator< value_type, traits >::type key_comparator; # endif -- typedef typename options::disposer disposer ; ///< disposer used ++ typedef typename traits::disposer disposer; ///< disposer used typedef typename get_node_traits< value_type, node_type, hook>::type node_traits ; ///< node traits -- typedef typename michael_list::get_link_checker< node_type, options::link_checker >::type link_checker ; ///< link checker ++ typedef typename michael_list::get_link_checker< node_type, traits::link_checker >::type link_checker; ///< link checker -- typedef gc::nogc gc ; ///< Garbage collector -- typedef typename options::back_off back_off ; ///< back-off strategy -- typedef typename options::item_counter item_counter ; ///< Item counting policy used -- typedef typename options::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option ++ typedef typename traits::back_off back_off; ///< back-off strategy ++ typedef typename traits::item_counter item_counter; ///< Item counting policy used ++ typedef typename traits::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option //@cond -- // Rebind options (split-list support) ++ // Rebind traits (split-list support) template -- struct rebind_options { ++ struct rebind_traits { typedef MichaelList< gc , value_type -- , typename cds::opt::make_options< options, Options...>::type ++ , typename cds::opt::make_options< traits, Options...>::type > type; }; //@endcond @@@ -83,8 -83,8 +88,8 @@@ typedef typename node_type::atomic_ptr atomic_node_ptr ; ///< Atomic node pointer typedef atomic_node_ptr auxiliary_head ; ///< Auxiliary head type (for split-list support) -- atomic_node_ptr m_pHead ; ///< Head pointer -- item_counter m_ItemCounter ; ///< Item counter ++ atomic_node_ptr m_pHead; ///< Head pointer ++ item_counter m_ItemCounter; ///< Item counter //@cond /// Position pointer for item search @@@ -97,25 -97,25 +102,25 @@@ protected: //@cond -- void clear_links( node_type * pNode ) ++ static void clear_links( node_type * pNode ) { pNode->m_pNext.store( nullptr, memory_model::memory_order_release ); } template -- void dispose_node( node_type * pNode, Disposer disp ) ++ static void dispose_node( node_type * pNode, Disposer disp ) { clear_links( pNode ); disp( node_traits::to_value_ptr( *pNode )); } template -- void dispose_value( value_type& val, Disposer disp ) ++ static void dispose_value( value_type& val, Disposer disp ) { dispose_node( node_traits::to_node_ptr( val ), disp ); } -- bool link_node( node_type * pNode, position& pos ) ++ static bool link_node( node_type * pNode, position& pos ) { assert( pNode != nullptr ); link_checker::is_empty( pNode ); @@@ -127,7 -127,7 +132,7 @@@ protected: //@cond -- template ++ template class iterator_type { friend class MichaelList; @@@ -162,8 -162,8 +167,8 @@@ } public: -- typedef typename cds::details::make_const_type::pointer value_ptr; -- typedef typename cds::details::make_const_type::reference value_ref; ++ typedef typename cds::details::make_const_type::pointer value_ptr; ++ typedef typename cds::details::make_const_type::reference value_ref; iterator_type() : m_pNode( nullptr ) @@@ -331,17 -331,17 +336,15 @@@ /// Finds the key \p val /** \anchor cds_intrusive_MichaelList_nogc_find_func -- The function searches the item with key equal to \p val ++ The function searches the item with key equal to \p key and calls the functor \p f for item found. The interface of \p Func functor is: \code struct functor { -- void operator()( value_type& item, Q& val ); ++ void operator()( value_type& item, Q& key ); }; \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You can pass \p f argument by value or by reference using \p std::ref. ++ where \p item is the item found, \p key is the find function argument. The functor can change non-key fields of \p item. The function \p find does not serialize simultaneous access to the list \p item. If such access is @@@ -350,12 -350,12 +353,12 @@@ The function returns \p true if \p val is found, \p false otherwise. */ template -- bool find( Q& val, Func f ) ++ bool find( Q& key, Func f ) { -- return find_at( m_pHead, val, key_comparator(), f ); ++ return find_at( m_pHead, key, key_comparator(), f ); } -- /// Finds the key \p val using \p pred predicate for searching ++ /// Finds the key \p key using \p pred predicate for searching /** The function is an analog of \ref cds_intrusive_MichaelList_nogc_find_func "find(Q&, Func)" but \p pred is used for key comparing. @@@ -363,62 -363,62 +366,23 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool find_with( Q& val, Less pred, Func f ) ++ bool find_with( Q& key, Less pred, Func f ) { -- return find_at( m_pHead, val, cds::opt::details::make_comparator_from_less(), f ); ++ return find_at( m_pHead, key, cds::opt::details::make_comparator_from_less(), f ); } -- /// Finds the key \p val -- /** \anchor cds_intrusive_MichaelList_nogc_find_cfunc -- The function searches the item with key equal to \p val -- and calls the functor \p f for item found. -- The interface of \p Func functor is: -- \code -- struct functor { -- void operator()( value_type& item, Q const& val ); -- }; -- \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You can pass \p f argument by value or by reference using \p std::ref. -- -- The functor can change non-key fields of \p item. -- The function \p find does not serialize simultaneous access to the list \p item. If such access is -- possible you must provide your own synchronization schema to exclude unsafe item modifications. -- -- The function returns \p true if \p val is found, \p false otherwise. -- */ -- template -- bool find( Q const& val, Func f ) -- { -- return find_at( m_pHead, val, key_comparator(), f ); -- } -- -- /// Finds the key \p val using \p pred predicate for searching -- /** -- The function is an analog of \ref cds_intrusive_MichaelList_nogc_find_cfunc "find(Q const&, Func)" -- 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 -- bool find_with( Q const& val, Less pred, Func f ) -- { -- return find_at( m_pHead, val, cds::opt::details::make_comparator_from_less(), f ); -- } -- -- /// Finds the key \p val ++ /// Finds \p key /** \anchor cds_intrusive_MichaelList_nogc_find_val -- The function searches the item with key equal to \p val ++ The function searches the item with key equal to \p key and returns pointer to value found or \p nullptr. */ template -- value_type * find( Q const & val ) ++ value_type * find( Q const& key ) { -- return find_at( m_pHead, val, key_comparator() ); ++ return find_at( m_pHead, key, key_comparator() ); } -- /// Finds the key \p val using \p pred predicate for searching ++ /// Finds \p key using \p pred predicate for searching /** The function is an analog of \ref cds_intrusive_MichaelList_nogc_find_val "find(Q const&, Func)" but \p pred is used for key comparing. @@@ -426,9 -426,9 +390,9 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- value_type * find_with( Q const& val, Less pred ) ++ value_type * find_with( Q const& key, Less pred ) { -- return find_at( m_pHead, val, cds::opt::details::make_comparator_from_less()); ++ return find_at( m_pHead, key, cds::opt::details::make_comparator_from_less()); } /// Clears the list @@@ -468,11 -468,11 +432,11 @@@ /// Returns list's item count /** -- The value returned depends on opt::item_counter option. For atomics::empty_item_counter, ++ The value returned depends on item counter provided by \p Traits. For \p atomicity::empty_item_counter, this function always returns 0. -- Warning: even if you use real item counter and it returns 0, this fact is not mean that the list -- is empty. To check list emptyness use \ref empty() method. ++ @note Even if you use real item counter and it returns 0, this fact does not mean that the list ++ is empty. To check list emptyness use \p empty() method. */ size_t size() const { diff --cc cds/intrusive/michael_list_rcu.h index 11925a4d,11925a4d..4ff82b57 --- a/cds/intrusive/michael_list_rcu.h +++ b/cds/intrusive/michael_list_rcu.h @@@ -6,6 -6,6 +6,7 @@@ #include #include #include ++#include #include namespace cds { namespace intrusive { @@@ -21,20 -21,20 +22,9 @@@ - \p RCU - one of \ref cds_urcu_gc "RCU type" - \p T - type to be stored in the list; the type \p T should be based on (or has a member of type) cds::intrusive::micheal_list::node -- - \p Traits - type traits. See michael_list::type_traits for explanation. -- -- It is possible to declare option-based list with \p %cds::intrusive::michael_list::make_traits metafunction istead of \p Traits template -- argument. Template argument list \p Options of cds::intrusive::michael_list::make_traits metafunction are: -- - opt::hook - hook used. Possible values are: michael_list::base_hook, michael_list::member_hook, michael_list::traits_hook. -- If the option is not specified, michael_list::base_hook<> is used. -- - opt::compare - key comparison functor. No default functor is provided. -- If the option is not specified, the opt::less is used. -- - opt::less - specifies binary predicate used for key comparison. Default is \p std::less. -- - opt::disposer - the functor used for dispose removed items. Default is opt::v::empty_disposer -- - opt::rcu_check_deadlock - a deadlock checking policy. Default is opt::v::rcu_throw_deadlock -- - opt::item_counter - the type of item counting feature. Default is \ref atomicity::empty_item_counter -- - opt::memory_model - C++ memory ordering model. Can be opt::v::relaxed_ordering (relaxed memory model, the default) -- or opt::v::sequential_consistent (sequentially consisnent memory model). ++ - \p Traits - type traits. See \p michael_list::traits for explanation. It is possible to declare option-based ++ list with \p cds::intrusive::michael_list::make_traits metafunction, ++ see \ref cds_intrusive_MichaelList_hp "here" for explanations. \par Usage Before including you should include appropriate RCU header file, @@@ -48,43 -48,43 +38,49 @@@ typedef cds::intrusive::MichaelList >, Foo > rcu_michael_list; \endcode */ -- template < typename RCU, typename T, class Traits > ++ template < typename RCU, typename T, ++#ifdef CDS_DOXYGEN_INVOKED ++ class Traits = michael_list::traits ++#else ++ class Traits ++#endif ++ > class MichaelList, T, Traits> { public: -- typedef T value_type ; ///< type of value stored in the queue -- typedef Traits options ; ///< Traits template parameter ++ typedef T value_type; ///< type of value stored in the list ++ typedef Traits traits; ///< Traits template parameter -- typedef typename options::hook hook ; ///< hook type -- typedef typename hook::node_type node_type ; ///< node type ++ typedef typename traits::hook hook; ///< hook type ++ typedef typename hook::node_type node_type; ///< node type # ifdef CDS_DOXYGEN_INVOKED typedef implementation_defined key_comparator ; ///< key comparison functor based on opt::compare and opt::less option setter. # else -- typedef typename opt::details::make_comparator< value_type, options >::type key_comparator; ++ typedef typename opt::details::make_comparator< value_type, traits >::type key_comparator; # endif -- typedef typename options::disposer disposer ; ///< disposer used ++ typedef typename traits::disposer disposer; ///< disposer used typedef typename get_node_traits< value_type, node_type, hook>::type node_traits ; ///< node traits -- typedef typename michael_list::get_link_checker< node_type, options::link_checker >::type link_checker ; ///< link checker ++ typedef typename michael_list::get_link_checker< node_type, traits::link_checker >::type link_checker; ///< link checker -- typedef cds::urcu::gc gc ; ///< RCU schema -- typedef typename options::back_off back_off ; ///< back-off strategy -- typedef typename options::item_counter item_counter; ///< Item counting policy used -- typedef typename options::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option -- typedef typename options::rcu_check_deadlock rcu_check_deadlock ; ///< Deadlock checking policy ++ typedef cds::urcu::gc gc; ///< RCU schema ++ typedef typename traits::back_off back_off; ///< back-off strategy ++ typedef typename traits::item_counter item_counter; ///< Item counting policy used ++ typedef typename traits::memory_model memory_model; ///< Memory ordering. See cds::opt::memory_model option ++ typedef typename traits::rcu_check_deadlock rcu_check_deadlock; ///< Deadlock checking policy typedef typename gc::scoped_lock rcu_lock ; ///< RCU scoped lock static CDS_CONSTEXPR const bool c_bExtractLockExternal = true; ///< Group of \p extract_xxx functions require external locking //@cond -- // Rebind options (split-list support) ++ // Rebind traits (split-list support) template -- struct rebind_options { ++ struct rebind_traits { typedef MichaelList< gc , value_type -- , typename cds::opt::make_options< options, Options...>::type ++ , typename cds::opt::make_options< traits, Options...>::type > type; }; //@endcond @@@ -333,7 -333,7 +329,7 @@@ The function allows to split new item creating into two part: - create item with key only - insert new item into the list -- - if inserting is success, calls \p f functor to initialize value-field of \p val. ++ - if inserting is success, calls \p f functor to initialize value-field of \p val. The functor signature is: \code @@@ -341,8 -341,8 +337,7 @@@ \endcode where \p val is the item inserted. User-defined functor \p f should guarantee that during changing \p val no any other changes could be made on this list's item by concurrent threads. -- The user-defined functor is called only if the inserting is success and may be passed by reference -- using \p std::ref. ++ The user-defined functor is called only if the inserting is success. The function makes RCU lock internally. */ @@@ -374,15 -374,15 +369,12 @@@ The functor may change non-key fields of the \p item; however, \p func must guarantee that during changing no any other modifications could be made on this item by concurrent threads. -- You can pass \p func argument by value or by reference using \p std::ref. -- Returns std::pair where \p first is true if operation is successfull, \p second is true if new item has been added or \p false if the item with \p key already is in the list. The function makes RCU lock internally. */ -- template std::pair ensure( value_type& val, Func func ) { @@@ -396,7 -396,7 +388,7 @@@ Difference between \ref erase and \p unlink functions: \p erase finds a key and deletes the item found. \p unlink finds an item by key and deletes it -- only if \p val is an item of that list, i.e. the pointer to item found ++ only if \p val is an item of that list, i.e. the pointer to the item found is equal to &val . The function returns \p true if success and \p false otherwise. @@@ -414,20 -414,20 +406,20 @@@ /// Deletes the item from the list /** \anchor cds_intrusive_MichaelList_rcu_erase_val -- The function searches an item with key equal to \p val in the list, ++ The function searches an item with key equal to \p key in the list, unlinks it from the list, and returns \p true. -- If the item with the key equal to \p val is not found the function return \p false. ++ If the item with the key equal to \p key is not found the function return \p false. RCU \p synchronize method can be called. Note that depending on RCU type used the \ref disposer call can be deferred. The function can throw \ref cds_urcu_rcu_deadlock "cds::urcu::rcu_deadlock" exception if a deadlock is detected and -- the deadlock checking policy is opt::v::rcu_throw_deadlock. ++ the deadlock checking policy is \p opt::v::rcu_throw_deadlock. */ template -- bool erase( Q const& val ) ++ bool erase( Q const& key ) { -- return erase_at( m_pHead, val, key_comparator() ); ++ return erase_at( m_pHead, key, key_comparator() ); } /// Deletes the item from the list using \p pred predicate for searching @@@ -438,14 -438,14 +430,14 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool erase_with( Q const& val, Less pred ) ++ bool erase_with( Q const& key, Less pred ) { -- return erase_at( m_pHead, val, cds::opt::details::make_comparator_from_less() ); ++ return erase_at( m_pHead, key, cds::opt::details::make_comparator_from_less() ); } /// Deletes the item from the list /** \anchor cds_intrusive_MichaelList_rcu_erase_func -- The function searches an item with key equal to \p val in the list, ++ The function searches an item with key equal to \p key in the list, call \p func functor with item found, unlinks it from the list, and returns \p true. The \p Func interface is \code @@@ -453,20 -453,20 +445,19 @@@ void operator()( value_type const& item ); }; \endcode -- The functor may be passed by reference using boost:ref -- If the item with the key equal to \p val is not found the function return \p false. ++ If the item with the key equal to \p key is not found the function return \p false. RCU \p synchronize method can be called. Note that depending on RCU type used the \ref disposer call can be deferred. The function can throw \ref cds_urcu_rcu_deadlock "cds::urcu::rcu_deadlock" exception if a deadlock is detected and -- the deadlock checking policy is opt::v::rcu_throw_deadlock. ++ the deadlock checking policy is \p opt::v::rcu_throw_deadlock. */ template -- bool erase( Q const& val, Func func ) ++ bool erase( Q const& key, Func func ) { -- return erase_at( m_pHead, val, key_comparator(), func ); ++ return erase_at( m_pHead, key, key_comparator(), func ); } /// Deletes the item from the list using \p pred predicate for searching @@@ -477,21 -477,21 +468,20 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool erase_with( Q const& val, Less pred, Func func ) ++ bool erase_with( Q const& key, Less pred, Func func ) { -- return erase_at( m_pHead, val, cds::opt::details::make_comparator_from_less(), func ); ++ return erase_at( m_pHead, key, cds::opt::details::make_comparator_from_less(), func ); } /// Extracts an item from the list /** @anchor cds_intrusive_MichaelList_rcu_extract -- The function searches an item with key equal to \p val in the list, ++ The function searches an item with key equal to \p key in the list, unlinks it from the list, and returns pointer to an item found in \p dest parameter. -- If the item with the key equal to \p val is not found the function returns \p false, -- \p dest is empty. ++ If \p key is not found the function returns \p false, \p dest is empty. @note The function does NOT call RCU read-side lock or synchronization, -- and does NOT dispose the item found. It just excludes the item from the list ++ and does NOT dispose the item found. It just unlinks the item from the list and returns a pointer to item found. You should lock RCU before calling this function, and you should manually release \p dest exempt pointer outside the RCU lock before reusing the pointer. @@@ -526,9 -526,9 +516,9 @@@ \endcode */ template -- bool extract( exempt_ptr& dest, Q const& val ) ++ bool extract( exempt_ptr& dest, Q const& key ) { -- dest = extract_at( m_pHead, val, key_comparator() ); ++ dest = extract_at( m_pHead, key, key_comparator() ); return !dest.empty(); } @@@ -541,25 -541,25 +531,23 @@@ \p pred must imply the same element order as \ref key_comparator. */ template -- bool extract_with( exempt_ptr& dest, Q const& val, Less pred ) ++ bool extract_with( exempt_ptr& dest, Q const& key, Less pred ) { -- dest = extract_at( m_pHead, val, cds::opt::details::make_comparator_from_less() ); ++ dest = extract_at( m_pHead, key, cds::opt::details::make_comparator_from_less() ); return !dest.empty(); } /// Find the key \p val /** \anchor cds_intrusive_MichaelList_rcu_find_func -- The function searches the item with key equal to \p val ++ The function searches the item with key equal to \p key and calls the functor \p f for item found. The interface of \p Func functor is: \code struct functor { -- void operator()( value_type& item, Q& val ); ++ void operator()( value_type& item, Q& key ); }; \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You can pass \p f argument by value or by reference using \p std::ref. ++ where \p item is the item found, \p key is the find function argument. The functor can change non-key fields of \p item. The function \p find does not serialize simultaneous access to the list \p item. If such access is @@@ -570,12 -570,12 +558,12 @@@ The function returns \p true if \p val is found, \p false otherwise. */ template -- bool find( Q& val, Func f ) const ++ bool find( Q& key, Func f ) const { -- return find_at( const_cast(m_pHead), val, key_comparator(), f ); ++ return find_at( const_cast(m_pHead), key, key_comparator(), f ); } -- /// Finds the key \p val using \p pred predicate for searching ++ /// Finds \p key using \p pred predicate for searching /** The function is an analog of \ref cds_intrusive_MichaelList_rcu_find_func "find(Q&, Func)" but \p pred is used for key comparing. @@@ -583,64 -583,64 +571,23 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool find_with( Q& val, Less pred, Func f ) const -- { -- return find_at( const_cast( m_pHead ), val, cds::opt::details::make_comparator_from_less(), f ); -- } -- -- /// Find the key \p val -- /** \anchor cds_intrusive_MichaelList_rcu_find_cfunc -- The function searches the item with key equal to \p val -- and calls the functor \p f for item found. -- The interface of \p Func functor is: -- \code -- struct functor { -- void operator()( value_type& item, Q const& val ); -- }; -- \endcode -- where \p item is the item found, \p val is the find function argument. -- -- You can pass \p f argument by value or by reference using \p std::ref. -- -- The functor can change non-key fields of \p item. -- The function \p find does not serialize simultaneous access to the list \p item. If such access is -- possible you must provide your own synchronization schema to exclude unsafe item modifications. -- -- The function makes RCU lock internally. -- -- The function returns \p true if \p val is found, \p false otherwise. -- */ -- template -- bool find( Q const& val, Func f ) const -- { -- return find_at( const_cast( m_pHead ), val, key_comparator(), f ); -- } -- -- /// Finds the key \p val using \p pred predicate for searching -- /** -- The function is an analog of \ref cds_intrusive_MichaelList_rcu_find_cfunc "find(Q const&, Func)" -- 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 -- bool find_with( Q const& val, Less pred, Func f ) const ++ bool find_with( Q& key, Less pred, Func f ) const { -- return find_at( const_cast( m_pHead ), val, cds::opt::details::make_comparator_from_less(), f ); ++ return find_at( const_cast( m_pHead ), key, cds::opt::details::make_comparator_from_less(), f ); } -- /// Find the key \p val ++ /// Finds \p key /** \anchor cds_intrusive_MichaelList_rcu_find_val -- The function searches the item with key equal to \p val ++ The function searches the item with key equal to \p key and returns \p true if \p val found or \p false otherwise. */ template -- bool find( Q const& val ) const ++ bool find( Q const& key ) const { -- return find_at( const_cast( m_pHead ), val, key_comparator() ); ++ return find_at( const_cast( m_pHead ), key, key_comparator() ); } -- /// Finds the key \p val using \p pred predicate for searching ++ /// Finds \p key using \p pred predicate for searching /** The function is an analog of \ref cds_intrusive_MichaelList_rcu_find_val "find(Q const&)" but \p pred is used for key comparing. @@@ -648,15 -648,15 +595,15 @@@ \p pred must imply the same element order as the comparator used for building the list. */ template -- bool find_with( Q const& val, Less pred ) const ++ bool find_with( Q const& key, Less pred ) const { -- return find_at( const_cast( m_pHead ), val, cds::opt::details::make_comparator_from_less() ); ++ return find_at( const_cast( m_pHead ), key, cds::opt::details::make_comparator_from_less() ); } -- /// Finds the key \p val and return the item found ++ /// Finds \p key and return the item found /** \anchor cds_intrusive_MichaelList_rcu_get -- The function searches the item with key equal to \p val and returns the pointer to item found. -- If \p val is not found it returns \p nullptr. ++ The function searches the item with key equal to \p key and returns the pointer to item found. ++ If \p key is not found it returns \p nullptr. Note the compare functor should accept a parameter of type \p Q that can be not the same as \p value_type. @@@ -681,29 -681,29 +628,29 @@@ \endcode */ template -- value_type * get( Q const& val ) const ++ value_type * get( Q const& key ) const { -- return get_at( const_cast( m_pHead ), val, key_comparator()); ++ return get_at( const_cast( m_pHead ), key, key_comparator()); } -- /// Finds the key \p val and return the item found ++ /// Finds \p key and return the item found /** The function is an analog of \ref cds_intrusive_MichaelList_rcu_get "get(Q const&)" but \p pred is used for comparing the keys. -- \p Less functor has the semantics like \p std::less but should take arguments of type \ref value_type and \p Q ++ \p Less functor has the semantics like \p std::less but should take arguments of type \p value_type and \p Q in any order. \p pred must imply the same element order as the comparator used for building the list. */ template -- value_type * get_with( Q const& val, Less pred ) const ++ value_type * get_with( Q const& key, Less pred ) const { -- return get_at( const_cast( m_pHead ), val, cds::opt::details::make_comparator_from_less()); ++ return get_at( const_cast( m_pHead ), key, cds::opt::details::make_comparator_from_less()); } /// Clears the list using default disposer /** -- The function clears the list using default (provided in class template) disposer functor. ++ The function clears the list using default (provided by \p Traits class template argument) disposer functor. RCU \p synchronize method can be called. Note that depending on RCU type used the \ref disposer invocation can be deferred. @@@ -744,11 -744,11 +691,11 @@@ /// Returns list's item count /** -- The value returned depends on opt::item_counter option. For atomics::empty_item_counter, ++ The value returned depends on item counter provided by \p Traits. For \p atomicity::empty_item_counter, this function always returns 0. -- Warning: even if you use real item counter and it returns 0, this fact is not mean that the list -- is empty. To check list emptyness use \ref empty() method. ++ @note Even if you use real item counter and it returns 0, this fact does not mean that the list ++ is empty. To check list emptyness use \p empty() method. */ size_t size() const { diff --cc cds/intrusive/msqueue.h index 7dcf1f10,7dcf1f10..088f763d --- a/cds/intrusive/msqueue.h +++ b/cds/intrusive/msqueue.h @@@ -306,7 -306,7 +306,7 @@@ namespace cds { namespace intrusive > barQueue; \endcode */ -- template ++ template class MSQueue { public: diff --cc cds/intrusive/split_list.h index acab1ea3,acab1ea3..ed9f5111 --- a/cds/intrusive/split_list.h +++ b/cds/intrusive/split_list.h @@@ -17,7 -17,7 +17,7 @@@ namespace cds { namespace intrusive The split-ordered list is a lock-free implementation of an extensible unbounded hash table. It uses original recursive split-ordering algorithm discovered by Ori Shalev and Nir Shavit that allows to split buckets -- without moving an item on resizing. ++ without items moving on resizing. \anchor cds_SplitList_algo_desc Short description diff --cc projects/Win/vc12/hdr-test-ordered-list.vcxproj index 42bf92e8,42bf92e8..4c2e1948 --- a/projects/Win/vc12/hdr-test-ordered-list.vcxproj +++ b/projects/Win/vc12/hdr-test-ordered-list.vcxproj @@@ -552,6 -552,6 +552,7 @@@ ++ @@@ -559,7 -559,7 +560,6 @@@ -- @@@ -578,17 -578,17 +578,17 @@@ ++ ++ -- -- diff --cc projects/Win/vc12/hdr-test-ordered-list.vcxproj.filters index 769b3aa0,769b3aa0..bf668835 --- a/projects/Win/vc12/hdr-test-ordered-list.vcxproj.filters +++ b/projects/Win/vc12/hdr-test-ordered-list.vcxproj.filters @@@ -37,9 -37,9 +37,6 @@@ intrusive -- -- intrusive -- container @@@ -82,15 -82,15 +79,9 @@@ container -- -- container -- container -- -- container -- container @@@ -154,6 -154,6 +145,15 @@@ container ++ ++ intrusive ++ ++ ++ container ++ ++ ++ container ++ diff --cc projects/source.test-hdr.mk index 05830ba4,05830ba4..6e77b123 --- a/projects/source.test-hdr.mk +++ b/projects/source.test-hdr.mk @@@ -83,17 -83,17 +83,17 @@@ CDS_TESTHDR_ORDLIST := tests/test-hdr/ordered_list/hdr_lazy_kv_rcu_gpt.cpp \ tests/test-hdr/ordered_list/hdr_lazy_kv_rcu_shb.cpp \ tests/test-hdr/ordered_list/hdr_lazy_kv_rcu_sht.cpp \ ++ tests/test-hdr/ordered_list/hdr_michael_dhp.cpp \ tests/test-hdr/ordered_list/hdr_michael_hp.cpp \ tests/test-hdr/ordered_list/hdr_michael_nogc.cpp \ -- tests/test-hdr/ordered_list/hdr_michael_ptb.cpp \ tests/test-hdr/ordered_list/hdr_michael_rcu_gpi.cpp \ tests/test-hdr/ordered_list/hdr_michael_rcu_gpb.cpp \ tests/test-hdr/ordered_list/hdr_michael_rcu_gpt.cpp \ tests/test-hdr/ordered_list/hdr_michael_rcu_shb.cpp \ tests/test-hdr/ordered_list/hdr_michael_rcu_sht.cpp \ ++ tests/test-hdr/ordered_list/hdr_michael_kv_dhp.cpp \ tests/test-hdr/ordered_list/hdr_michael_kv_hp.cpp \ tests/test-hdr/ordered_list/hdr_michael_kv_nogc.cpp \ -- tests/test-hdr/ordered_list/hdr_michael_kv_ptb.cpp \ tests/test-hdr/ordered_list/hdr_michael_kv_rcu_gpi.cpp \ tests/test-hdr/ordered_list/hdr_michael_kv_rcu_gpb.cpp \ tests/test-hdr/ordered_list/hdr_michael_kv_rcu_gpt.cpp \ diff --cc projects/source.test-hdr.offsetof.mk index d2da5258,d2da5258..4ac669ba --- a/projects/source.test-hdr.offsetof.mk +++ b/projects/source.test-hdr.offsetof.mk @@@ -59,7 -59,7 +59,7 @@@ CDS_TESTHDR_OFFSETOF_ORDLIST := tests/test-hdr/ordered_list/hdr_intrusive_lazy_rcu_sht.cpp \ tests/test-hdr/ordered_list/hdr_intrusive_michael_hp.cpp \ tests/test-hdr/ordered_list/hdr_intrusive_michael_nogc.cpp \ -- tests/test-hdr/ordered_list/hdr_intrusive_michael_ptb.cpp \ ++ tests/test-hdr/ordered_list/hdr_intrusive_michael_dhp.cpp \ tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpb.cpp \ tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpi.cpp \ tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpt.cpp \ diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael.h index 699beb01,699beb01..557f4396 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael.h +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael.h @@@ -753,14 -753,14 +753,14 @@@ namespace ordlist void HP_member_cmpmix(); void HP_member_ic(); -- void PTB_base_cmp(); -- void PTB_base_less(); -- void PTB_base_cmpmix(); -- void PTB_base_ic(); -- void PTB_member_cmp(); -- void PTB_member_less(); -- void PTB_member_cmpmix(); -- void PTB_member_ic(); ++ void DHP_base_cmp(); ++ void DHP_base_less(); ++ void DHP_base_cmpmix(); ++ void DHP_base_ic(); ++ void DHP_member_cmp(); ++ void DHP_member_less(); ++ void DHP_member_cmpmix(); ++ void DHP_member_ic(); void RCU_GPI_base_cmp(); void RCU_GPI_base_less(); @@@ -827,14 -827,14 +827,14 @@@ CPPUNIT_TEST(HP_member_cmpmix) CPPUNIT_TEST(HP_member_ic) -- CPPUNIT_TEST(PTB_base_cmp) -- CPPUNIT_TEST(PTB_base_less) -- CPPUNIT_TEST(PTB_base_cmpmix) -- CPPUNIT_TEST(PTB_base_ic) -- CPPUNIT_TEST(PTB_member_cmp) -- CPPUNIT_TEST(PTB_member_less) -- CPPUNIT_TEST(PTB_member_cmpmix) -- CPPUNIT_TEST(PTB_member_ic) ++ CPPUNIT_TEST(DHP_base_cmp) ++ CPPUNIT_TEST(DHP_base_less) ++ CPPUNIT_TEST(DHP_base_cmpmix) ++ CPPUNIT_TEST(DHP_base_ic) ++ CPPUNIT_TEST(DHP_member_cmp) ++ CPPUNIT_TEST(DHP_member_less) ++ CPPUNIT_TEST(DHP_member_cmpmix) ++ CPPUNIT_TEST(DHP_member_ic) CPPUNIT_TEST(RCU_GPI_base_cmp) CPPUNIT_TEST(RCU_GPI_base_less) diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael_dhp.cpp index 00000000,fed0ec88..0efc72df mode 000000,100644..100644 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael_dhp.cpp +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael_dhp.cpp @@@ -1,0 -1,129 +1,127 @@@ + //$$CDS-header$$ + + #include "ordered_list/hdr_intrusive_michael.h" + #include + + namespace ordlist { - void IntrusiveMichaelListHeaderTest::PTB_base_cmp() ++ void IntrusiveMichaelListHeaderTest::DHP_base_cmp() + { - typedef base_int_item< cds::gc::PTB > item; - typedef ci::MichaelList< cds::gc::PTB - ,item - ,ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< co::gc > > - ,co::compare< cmp > - ,ci::opt::disposer< faked_disposer > - >::type - > list; ++ typedef base_int_item< cds::gc::DHP > item; ++ struct traits : public ci::michael_list::traits { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef cmp compare; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< cds::gc::DHP, item, traits > list; + test_int(); + } - void IntrusiveMichaelListHeaderTest::PTB_base_less() ++ void IntrusiveMichaelListHeaderTest::DHP_base_less() + { - typedef base_int_item< cds::gc::PTB > item; - typedef ci::MichaelList< cds::gc::PTB ++ typedef base_int_item< cds::gc::DHP > item; ++ typedef ci::MichaelList< cds::gc::DHP + ,item + ,ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< co::gc > > ++ ci::opt::hook< ci::michael_list::base_hook< co::gc > > + ,co::less< less > + ,ci::opt::disposer< faked_disposer > + >::type + > list; + test_int(); + } - void IntrusiveMichaelListHeaderTest::PTB_base_cmpmix() ++ void IntrusiveMichaelListHeaderTest::DHP_base_cmpmix() + { - typedef base_int_item< cds::gc::PTB > item; - typedef ci::MichaelList< cds::gc::PTB ++ typedef base_int_item< cds::gc::DHP > item; ++ typedef ci::MichaelList< cds::gc::DHP + ,item + ,ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< co::gc > > ++ ci::opt::hook< ci::michael_list::base_hook< co::gc > > + ,co::less< less > + ,co::compare< cmp > + ,ci::opt::disposer< faked_disposer > + >::type + > list; + test_int(); + } - void IntrusiveMichaelListHeaderTest::PTB_base_ic() ++ void IntrusiveMichaelListHeaderTest::DHP_base_ic() + { - typedef base_int_item< cds::gc::PTB > item; - typedef ci::MichaelList< cds::gc::PTB ++ typedef base_int_item< cds::gc::DHP > item; ++ typedef ci::MichaelList< cds::gc::DHP + ,item + ,ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< co::gc > > ++ ci::opt::hook< ci::michael_list::base_hook< co::gc > > + ,co::less< less > + ,co::compare< cmp > + ,ci::opt::disposer< faked_disposer > + ,co::item_counter< cds::atomicity::item_counter > + >::type + > list; + test_int(); + } - void IntrusiveMichaelListHeaderTest::PTB_member_cmp() ++ void IntrusiveMichaelListHeaderTest::DHP_member_cmp() + { - typedef member_int_item< cds::gc::PTB > item; - typedef ci::MichaelList< cds::gc::PTB ++ typedef member_int_item< cds::gc::DHP > item; ++ typedef ci::MichaelList< cds::gc::DHP + ,item + ,ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< + offsetof( item, hMember ), - co::gc ++ co::gc + > > + ,co::compare< cmp > + ,ci::opt::disposer< faked_disposer > + >::type + > list; + test_int(); + } - void IntrusiveMichaelListHeaderTest::PTB_member_less() ++ void IntrusiveMichaelListHeaderTest::DHP_member_less() + { - typedef member_int_item< cds::gc::PTB > item; - typedef ci::MichaelList< cds::gc::PTB ++ typedef member_int_item< cds::gc::DHP > item; ++ typedef ci::MichaelList< cds::gc::DHP + ,item + ,ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< + offsetof( item, hMember ), - co::gc ++ co::gc + > > + ,co::less< less > + ,ci::opt::disposer< faked_disposer > + >::type + > list; + test_int(); + } - void IntrusiveMichaelListHeaderTest::PTB_member_cmpmix() ++ void IntrusiveMichaelListHeaderTest::DHP_member_cmpmix() + { - typedef member_int_item< cds::gc::PTB > item; - typedef ci::MichaelList< cds::gc::PTB ++ typedef member_int_item< cds::gc::DHP > item; ++ typedef ci::MichaelList< cds::gc::DHP + ,item + ,ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< + offsetof( item, hMember ), - co::gc ++ co::gc + > > + ,co::less< less > + ,co::compare< cmp > + ,ci::opt::disposer< faked_disposer > + >::type + > list; + test_int(); + } - void IntrusiveMichaelListHeaderTest::PTB_member_ic() ++ void IntrusiveMichaelListHeaderTest::DHP_member_ic() + { - typedef member_int_item< cds::gc::PTB > item; - typedef ci::MichaelList< cds::gc::PTB ++ typedef member_int_item< cds::gc::DHP > item; ++ typedef ci::MichaelList< cds::gc::DHP + ,item + ,ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< + offsetof( item, hMember ), - co::gc ++ co::gc + > > + ,co::compare< cmp > + ,ci::opt::disposer< faked_disposer > + ,co::item_counter< cds::atomicity::item_counter > + >::type + > list; + test_int(); + } + + } // namespace ordlist diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael_hp.cpp index 9e568fac,9e568fac..2e2c9f35 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael_hp.cpp +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael_hp.cpp @@@ -7,14 -7,14 +7,12 @@@ namespace ordlist void IntrusiveMichaelListHeaderTest::HP_base_cmp() { typedef base_int_item< cds::gc::HP > item; -- typedef ci::MichaelList< cds::gc::HP -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::compare< cmp > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef cmp compare; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< cds::gc::HP, item, traits > list; test_int(); } void IntrusiveMichaelListHeaderTest::HP_base_less() diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpb.cpp index 03c4ded5,03c4ded5..996030f5 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpb.cpp +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpb.cpp @@@ -12,27 -12,27 +12,25 @@@ namespace ordlist void IntrusiveMichaelListHeaderTest::RCU_GPB_base_cmp() { typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::compare< cmp > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef cmp compare; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); } void IntrusiveMichaelListHeaderTest::RCU_GPB_base_less() { typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::less< less > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef IntrusiveMichaelListHeaderTest::less less; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); } void IntrusiveMichaelListHeaderTest::RCU_GPB_base_cmpmix() diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpi.cpp index 3ed41ee0,3ed41ee0..7953a1c4 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpi.cpp +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpi.cpp @@@ -12,27 -12,27 +12,25 @@@ namespace ordlist void IntrusiveMichaelListHeaderTest::RCU_GPI_base_cmp() { typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::compare< cmp > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef cmp compare; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); } void IntrusiveMichaelListHeaderTest::RCU_GPI_base_less() { typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::less< less > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef IntrusiveMichaelListHeaderTest::less less; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); } void IntrusiveMichaelListHeaderTest::RCU_GPI_base_cmpmix() diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpt.cpp index 27e400da,27e400da..4f8d7f36 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpt.cpp +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_gpt.cpp @@@ -12,27 -12,27 +12,25 @@@ namespace ordlist void IntrusiveMichaelListHeaderTest::RCU_GPT_base_cmp() { typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::compare< cmp > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef cmp compare; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); } void IntrusiveMichaelListHeaderTest::RCU_GPT_base_less() { typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::less< less > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef IntrusiveMichaelListHeaderTest::less less; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); } void IntrusiveMichaelListHeaderTest::RCU_GPT_base_cmpmix() diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_shb.cpp index b6af0e69,b6af0e69..92950de7 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_shb.cpp +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_shb.cpp @@@ -15,14 -15,14 +15,13 @@@ namespace ordlist { #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::compare< cmp > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef cmp compare; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); #endif } @@@ -30,14 -30,14 +29,13 @@@ { #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::less< less > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef IntrusiveMichaelListHeaderTest::less less; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); #endif } diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_sht.cpp index bcd07cb5,bcd07cb5..174988cc --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_sht.cpp +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael_list_rcu_sht.cpp @@@ -15,14 -15,14 +15,13 @@@ namespace ordlist { #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::compare< cmp > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef cmp compare; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); #endif } @@@ -30,14 -30,14 +29,13 @@@ { #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED typedef base_int_item< RCU > item; -- typedef ci::MichaelList< RCU -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::less< less > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef IntrusiveMichaelListHeaderTest::less less; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< RCU, item, traits > list; test_rcu_int(); #endif } diff --cc tests/test-hdr/ordered_list/hdr_intrusive_michael_nogc.cpp index aeefabb1,aeefabb1..81f97104 --- a/tests/test-hdr/ordered_list/hdr_intrusive_michael_nogc.cpp +++ b/tests/test-hdr/ordered_list/hdr_intrusive_michael_nogc.cpp @@@ -7,27 -7,27 +7,25 @@@ namespace ordlist void IntrusiveMichaelListHeaderTest::nogc_base_cmp() { typedef base_int_item< cds::gc::nogc > item; -- typedef ci::MichaelList< cds::gc::nogc -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::compare< cmp > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef cmp compare; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< cds::gc::nogc, item, traits > list; test_nogc_int(); } void IntrusiveMichaelListHeaderTest::nogc_base_less() { typedef base_int_item< cds::gc::nogc > item; -- typedef ci::MichaelList< cds::gc::nogc -- ,item -- ,ci::michael_list::make_traits< -- ci::opt::hook< ci::michael_list::base_hook< co::gc > > -- ,co::less< less > -- ,ci::opt::disposer< faked_disposer > -- >::type -- > list; ++ struct traits : public ci::michael_list::traits ++ { ++ typedef ci::michael_list::base_hook< co::gc > hook; ++ typedef IntrusiveMichaelListHeaderTest::less less; ++ typedef faked_disposer disposer; ++ }; ++ typedef ci::MichaelList< cds::gc::nogc, item, traits > list; test_nogc_int(); } void IntrusiveMichaelListHeaderTest::nogc_base_cmpmix() diff --cc tests/test-hdr/ordered_list/hdr_michael.h index b7954622,b7954622..3036a557 --- a/tests/test-hdr/ordered_list/hdr_michael.h +++ b/tests/test-hdr/ordered_list/hdr_michael.h @@@ -679,10 -679,10 +679,10 @@@ namespace ordlist void HP_cmpmix(); void HP_ic(); -- void PTB_cmp(); -- void PTB_less(); -- void PTB_cmpmix(); -- void PTB_ic(); ++ void DHP_cmp(); ++ void DHP_less(); ++ void DHP_cmpmix(); ++ void DHP_ic(); void RCU_GPI_cmp(); void RCU_GPI_less(); @@@ -720,10 -720,10 +720,10 @@@ CPPUNIT_TEST(HP_cmpmix) CPPUNIT_TEST(HP_ic) -- CPPUNIT_TEST(PTB_cmp) -- CPPUNIT_TEST(PTB_less) -- CPPUNIT_TEST(PTB_cmpmix) -- CPPUNIT_TEST(PTB_ic) ++ CPPUNIT_TEST(DHP_cmp) ++ CPPUNIT_TEST(DHP_less) ++ CPPUNIT_TEST(DHP_cmpmix) ++ CPPUNIT_TEST(DHP_ic) CPPUNIT_TEST(RCU_GPI_cmp) CPPUNIT_TEST(RCU_GPI_less) diff --cc tests/test-hdr/ordered_list/hdr_michael_dhp.cpp index 00000000,0dfb8ac0..7c6fd1d5 mode 000000,100644..100644 --- a/tests/test-hdr/ordered_list/hdr_michael_dhp.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_dhp.cpp @@@ -1,0 -1,100 +1,100 @@@ + //$$CDS-header$$ + + #include "ordered_list/hdr_michael.h" + #include + + namespace ordlist { + namespace { - struct PTB_cmp_traits: public cc::michael_list::type_traits ++ struct DHP_cmp_traits: public cc::michael_list::traits + { + typedef MichaelListTestHeader::cmp compare; + }; + } - void MichaelListTestHeader::PTB_cmp() ++ void MichaelListTestHeader::DHP_cmp() + { + // traits-based version - typedef cc::MichaelList< cds::gc::PTB, item, PTB_cmp_traits > list; ++ typedef cc::MichaelList< cds::gc::DHP, item, DHP_cmp_traits > list; + test< list >(); + + // option-based version + - typedef cc::MichaelList< cds::gc::PTB, item, ++ typedef cc::MichaelList< cds::gc::DHP, item, + cc::michael_list::make_traits< + cc::opt::compare< cmp > + >::type + > opt_list; + test< opt_list >(); + } + + namespace { - struct PTB_less_traits: public cc::michael_list::type_traits ++ struct DHP_less_traits: public cc::michael_list::traits + { + typedef MichaelListTestHeader::lt less; + }; + } - void MichaelListTestHeader::PTB_less() ++ void MichaelListTestHeader::DHP_less() + { + // traits-based version - typedef cc::MichaelList< cds::gc::PTB, item, PTB_less_traits > list; ++ typedef cc::MichaelList< cds::gc::DHP, item, DHP_less_traits > list; + test< list >(); + + // option-based version + - typedef cc::MichaelList< cds::gc::PTB, item, ++ typedef cc::MichaelList< cds::gc::DHP, item, + cc::michael_list::make_traits< + cc::opt::less< lt > + >::type + > opt_list; + test< opt_list >(); + } + + namespace { - struct PTB_cmpmix_traits: public cc::michael_list::type_traits ++ struct DHP_cmpmix_traits: public cc::michael_list::traits + { + typedef MichaelListTestHeader::cmp compare; + typedef MichaelListTestHeader::lt less; + }; + } - void MichaelListTestHeader::PTB_cmpmix() ++ void MichaelListTestHeader::DHP_cmpmix() + { + // traits-based version - typedef cc::MichaelList< cds::gc::PTB, item, PTB_cmpmix_traits > list; ++ typedef cc::MichaelList< cds::gc::DHP, item, DHP_cmpmix_traits > list; + test< list >(); + + // option-based version + - typedef cc::MichaelList< cds::gc::PTB, item, ++ typedef cc::MichaelList< cds::gc::DHP, item, + cc::michael_list::make_traits< + cc::opt::compare< cmp > + ,cc::opt::less< lt > + >::type + > opt_list; + test< opt_list >(); + } + + namespace { - struct PTB_ic_traits: public cc::michael_list::type_traits ++ struct DHP_ic_traits: public cc::michael_list::traits + { + typedef MichaelListTestHeader::lt less; + typedef cds::atomicity::item_counter item_counter; + }; + } - void MichaelListTestHeader::PTB_ic() ++ void MichaelListTestHeader::DHP_ic() + { + // traits-based version - typedef cc::MichaelList< cds::gc::PTB, item, PTB_ic_traits > list; ++ typedef cc::MichaelList< cds::gc::DHP, item, DHP_ic_traits > list; + test< list >(); + + // option-based version + - typedef cc::MichaelList< cds::gc::PTB, item, ++ typedef cc::MichaelList< cds::gc::DHP, item, + cc::michael_list::make_traits< + cc::opt::less< lt > + ,cc::opt::item_counter< cds::atomicity::item_counter > + >::type + > opt_list; + test< opt_list >(); + } + + } // namespace ordlist + diff --cc tests/test-hdr/ordered_list/hdr_michael_hp.cpp index 5ad61d7d,5ad61d7d..132c0e06 --- a/tests/test-hdr/ordered_list/hdr_michael_hp.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_hp.cpp @@@ -5,7 -5,7 +5,7 @@@ namespace ordlist { namespace { -- struct HP_cmp_traits: public cc::michael_list::type_traits ++ struct HP_cmp_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; }; @@@ -28,7 -28,7 +28,7 @@@ } namespace { -- struct HP_less_traits: public cc::michael_list::type_traits ++ struct HP_less_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; }; @@@ -50,7 -50,7 +50,7 @@@ } namespace { -- struct HP_cmpmix_traits: public cc::michael_list::type_traits ++ struct HP_cmpmix_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; typedef MichaelListTestHeader::lt less; @@@ -74,7 -74,7 +74,7 @@@ } namespace { -- struct HP_ic_traits: public cc::michael_list::type_traits ++ struct HP_ic_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; typedef cds::atomicity::item_counter item_counter; diff --cc tests/test-hdr/ordered_list/hdr_michael_kv.h index b42ee6b2,b42ee6b2..1093774c --- a/tests/test-hdr/ordered_list/hdr_michael_kv.h +++ b/tests/test-hdr/ordered_list/hdr_michael_kv.h @@@ -602,10 -602,10 +602,10 @@@ namespace ordlist void HP_cmpmix(); void HP_ic(); -- void PTB_cmp(); -- void PTB_less(); -- void PTB_cmpmix(); -- void PTB_ic(); ++ void DHP_cmp(); ++ void DHP_less(); ++ void DHP_cmpmix(); ++ void DHP_ic(); void RCU_GPI_cmp(); void RCU_GPI_less(); @@@ -643,10 -643,10 +643,10 @@@ CPPUNIT_TEST(HP_cmpmix) CPPUNIT_TEST(HP_ic) -- CPPUNIT_TEST(PTB_cmp) -- CPPUNIT_TEST(PTB_less) -- CPPUNIT_TEST(PTB_cmpmix) -- CPPUNIT_TEST(PTB_ic) ++ CPPUNIT_TEST(DHP_cmp) ++ CPPUNIT_TEST(DHP_less) ++ CPPUNIT_TEST(DHP_cmpmix) ++ CPPUNIT_TEST(DHP_ic) CPPUNIT_TEST(RCU_GPI_cmp) CPPUNIT_TEST(RCU_GPI_less) diff --cc tests/test-hdr/ordered_list/hdr_michael_kv_dhp.cpp index 00000000,b66b3d37..e26c6b7d mode 000000,100644..100644 --- a/tests/test-hdr/ordered_list/hdr_michael_kv_dhp.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_kv_dhp.cpp @@@ -1,0 -1,100 +1,100 @@@ + //$$CDS-header$$ + + #include "ordered_list/hdr_michael_kv.h" + #include + + namespace ordlist { + namespace { - struct PTB_cmp_traits: public cc::michael_list::type_traits ++ struct DHP_cmp_traits: public cc::michael_list::traits + { + typedef MichaelKVListTestHeader::cmp compare; + }; + } - void MichaelKVListTestHeader::PTB_cmp() ++ void MichaelKVListTestHeader::DHP_cmp() + { + // traits-based version - typedef cc::MichaelKVList< cds::gc::PTB, key_type, value_type, PTB_cmp_traits > list; ++ typedef cc::MichaelKVList< cds::gc::DHP, key_type, value_type, DHP_cmp_traits > list; + test< list >(); + + // option-based version + - typedef cc::MichaelKVList< cds::gc::PTB, key_type, value_type, ++ typedef cc::MichaelKVList< cds::gc::DHP, key_type, value_type, + cc::michael_list::make_traits< + cc::opt::compare< cmp > + >::type + > opt_list; + test< opt_list >(); + } + + namespace { - struct PTB_less_traits: public cc::michael_list::type_traits ++ struct DHP_less_traits: public cc::michael_list::traits + { + typedef MichaelKVListTestHeader::lt less; + }; + } - void MichaelKVListTestHeader::PTB_less() ++ void MichaelKVListTestHeader::DHP_less() + { + // traits-based version - typedef cc::MichaelKVList< cds::gc::PTB, key_type, value_type, PTB_less_traits > list; ++ typedef cc::MichaelKVList< cds::gc::DHP, key_type, value_type, DHP_less_traits > list; + test< list >(); + + // option-based version + - typedef cc::MichaelKVList< cds::gc::PTB, key_type, value_type, ++ typedef cc::MichaelKVList< cds::gc::DHP, key_type, value_type, + cc::michael_list::make_traits< + cc::opt::less< lt > + >::type + > opt_list; + test< opt_list >(); + } + + namespace { - struct PTB_cmpmix_traits: public cc::michael_list::type_traits ++ struct DHP_cmpmix_traits: public cc::michael_list::traits + { + typedef MichaelKVListTestHeader::cmp compare; + typedef MichaelKVListTestHeader::lt less; + }; + } - void MichaelKVListTestHeader::PTB_cmpmix() ++ void MichaelKVListTestHeader::DHP_cmpmix() + { + // traits-based version - typedef cc::MichaelKVList< cds::gc::PTB, key_type, value_type, PTB_cmpmix_traits > list; ++ typedef cc::MichaelKVList< cds::gc::DHP, key_type, value_type, DHP_cmpmix_traits > list; + test< list >(); + + // option-based version + - typedef cc::MichaelKVList< cds::gc::PTB, key_type, value_type, ++ typedef cc::MichaelKVList< cds::gc::DHP, key_type, value_type, + cc::michael_list::make_traits< + cc::opt::compare< cmp > + ,cc::opt::less< lt > + >::type + > opt_list; + test< opt_list >(); + } + + namespace { - struct PTB_ic_traits: public cc::michael_list::type_traits ++ struct DHP_ic_traits: public cc::michael_list::traits + { + typedef MichaelKVListTestHeader::lt less; + typedef cds::atomicity::item_counter item_counter; + }; + } - void MichaelKVListTestHeader::PTB_ic() ++ void MichaelKVListTestHeader::DHP_ic() + { + // traits-based version - typedef cc::MichaelKVList< cds::gc::PTB, key_type, value_type, PTB_ic_traits > list; ++ typedef cc::MichaelKVList< cds::gc::DHP, key_type, value_type, DHP_ic_traits > list; + test< list >(); + + // option-based version + - typedef cc::MichaelKVList< cds::gc::PTB, key_type, value_type, ++ typedef cc::MichaelKVList< cds::gc::DHP, key_type, value_type, + cc::michael_list::make_traits< + cc::opt::less< lt > + ,cc::opt::item_counter< cds::atomicity::item_counter > + >::type + > opt_list; + test< opt_list >(); + } + + } // namespace ordlist + diff --cc tests/test-hdr/ordered_list/hdr_michael_kv_hp.cpp index 1c373234,1c373234..12012ed0 --- a/tests/test-hdr/ordered_list/hdr_michael_kv_hp.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_kv_hp.cpp @@@ -5,7 -5,7 +5,7 @@@ namespace ordlist { namespace { -- struct HP_cmp_traits: public cc::michael_list::type_traits ++ struct HP_cmp_traits: public cc::michael_list::traits { typedef MichaelKVListTestHeader::cmp compare; }; @@@ -30,7 -30,7 +30,7 @@@ } namespace { -- struct HP_less_traits: public cc::michael_list::type_traits ++ struct HP_less_traits : public cc::michael_list::traits { typedef MichaelKVListTestHeader::lt less; }; @@@ -52,7 -52,7 +52,7 @@@ } namespace { -- struct HP_cmpmix_traits: public cc::michael_list::type_traits ++ struct HP_cmpmix_traits : public cc::michael_list::traits { typedef MichaelKVListTestHeader::cmp compare; typedef MichaelKVListTestHeader::lt less; @@@ -76,7 -76,7 +76,7 @@@ } namespace { -- struct HP_ic_traits: public cc::michael_list::type_traits ++ struct HP_ic_traits : public cc::michael_list::traits { typedef MichaelKVListTestHeader::lt less; typedef cds::atomicity::item_counter item_counter; diff --cc tests/test-hdr/ordered_list/hdr_michael_rcu_gpb.cpp index 18d50f6e,18d50f6e..75c1e94c --- a/tests/test-hdr/ordered_list/hdr_michael_rcu_gpb.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_rcu_gpb.cpp @@@ -8,7 -8,7 +8,7 @@@ namespace ordlist namespace { typedef cds::urcu::gc< cds::urcu::general_buffered<> > rcu_type; -- struct RCU_GPB_cmp_traits: public cc::michael_list::type_traits ++ struct RCU_GPB_cmp_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; }; @@@ -31,7 -31,7 +31,7 @@@ } namespace { -- struct RCU_GPB_less_traits: public cc::michael_list::type_traits ++ struct RCU_GPB_less_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; }; @@@ -53,7 -53,7 +53,7 @@@ } namespace { -- struct RCU_GPB_cmpmix_traits: public cc::michael_list::type_traits ++ struct RCU_GPB_cmpmix_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; typedef MichaelListTestHeader::lt less; @@@ -77,7 -77,7 +77,7 @@@ } namespace { -- struct RCU_GPB_ic_traits: public cc::michael_list::type_traits ++ struct RCU_GPB_ic_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; typedef cds::atomicity::item_counter item_counter; diff --cc tests/test-hdr/ordered_list/hdr_michael_rcu_gpi.cpp index 1fe5d25a,1fe5d25a..5d912b10 --- a/tests/test-hdr/ordered_list/hdr_michael_rcu_gpi.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_rcu_gpi.cpp @@@ -8,7 -8,7 +8,7 @@@ namespace ordlist namespace { typedef cds::urcu::gc< cds::urcu::general_instant<> > rcu_type; -- struct RCU_GPI_cmp_traits: public cc::michael_list::type_traits ++ struct RCU_GPI_cmp_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; }; @@@ -31,7 -31,7 +31,7 @@@ } namespace { -- struct RCU_GPI_less_traits: public cc::michael_list::type_traits ++ struct RCU_GPI_less_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; }; @@@ -53,7 -53,7 +53,7 @@@ } namespace { -- struct RCU_GPI_cmpmix_traits: public cc::michael_list::type_traits ++ struct RCU_GPI_cmpmix_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; typedef MichaelListTestHeader::lt less; @@@ -77,7 -77,7 +77,7 @@@ } namespace { -- struct RCU_GPI_ic_traits: public cc::michael_list::type_traits ++ struct RCU_GPI_ic_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; typedef cds::atomicity::item_counter item_counter; diff --cc tests/test-hdr/ordered_list/hdr_michael_rcu_gpt.cpp index a53949e6,a53949e6..beee1042 --- a/tests/test-hdr/ordered_list/hdr_michael_rcu_gpt.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_rcu_gpt.cpp @@@ -8,7 -8,7 +8,7 @@@ namespace ordlist namespace { typedef cds::urcu::gc< cds::urcu::general_threaded<> > rcu_type; -- struct RCU_GPT_cmp_traits: public cc::michael_list::type_traits ++ struct RCU_GPT_cmp_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; }; @@@ -31,7 -31,7 +31,7 @@@ } namespace { -- struct RCU_GPT_less_traits: public cc::michael_list::type_traits ++ struct RCU_GPT_less_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; }; @@@ -53,7 -53,7 +53,7 @@@ } namespace { -- struct RCU_GPT_cmpmix_traits: public cc::michael_list::type_traits ++ struct RCU_GPT_cmpmix_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; typedef MichaelListTestHeader::lt less; @@@ -77,7 -77,7 +77,7 @@@ } namespace { -- struct RCU_GPT_ic_traits: public cc::michael_list::type_traits ++ struct RCU_GPT_ic_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; typedef cds::atomicity::item_counter item_counter; diff --cc tests/test-hdr/ordered_list/hdr_michael_rcu_shb.cpp index 00bfedb2,00bfedb2..19632db7 --- a/tests/test-hdr/ordered_list/hdr_michael_rcu_shb.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_rcu_shb.cpp @@@ -9,7 -9,7 +9,7 @@@ namespace ordlist namespace { typedef cds::urcu::gc< cds::urcu::signal_buffered<> > rcu_type; -- struct RCU_SHB_cmp_traits: public cc::michael_list::type_traits ++ struct RCU_SHB_cmp_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; }; @@@ -36,7 -36,7 +36,7 @@@ #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED namespace { -- struct RCU_SHB_less_traits: public cc::michael_list::type_traits ++ struct RCU_SHB_less_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; }; @@@ -62,7 -62,7 +62,7 @@@ #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED namespace { -- struct RCU_SHB_cmpmix_traits: public cc::michael_list::type_traits ++ struct RCU_SHB_cmpmix_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; typedef MichaelListTestHeader::lt less; @@@ -90,7 -90,7 +90,7 @@@ #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED namespace { -- struct RCU_SHB_ic_traits: public cc::michael_list::type_traits ++ struct RCU_SHB_ic_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; typedef cds::atomicity::item_counter item_counter; diff --cc tests/test-hdr/ordered_list/hdr_michael_rcu_sht.cpp index 2add5d8f,2add5d8f..7c74813d --- a/tests/test-hdr/ordered_list/hdr_michael_rcu_sht.cpp +++ b/tests/test-hdr/ordered_list/hdr_michael_rcu_sht.cpp @@@ -9,7 -9,7 +9,7 @@@ namespace ordlist namespace { typedef cds::urcu::gc< cds::urcu::signal_threaded<> > rcu_type; -- struct RCU_SHT_cmp_traits: public cc::michael_list::type_traits ++ struct RCU_SHT_cmp_traits : public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; }; @@@ -36,7 -36,7 +36,7 @@@ #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED namespace { -- struct RCU_SHT_less_traits: public cc::michael_list::type_traits ++ struct RCU_SHT_less_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; }; @@@ -62,7 -62,7 +62,7 @@@ #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED namespace { -- struct RCU_SHT_cmpmix_traits: public cc::michael_list::type_traits ++ struct RCU_SHT_cmpmix_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::cmp compare; typedef MichaelListTestHeader::lt less; @@@ -90,7 -90,7 +90,7 @@@ #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED namespace { -- struct RCU_SHT_ic_traits: public cc::michael_list::type_traits ++ struct RCU_SHT_ic_traits: public cc::michael_list::traits { typedef MichaelListTestHeader::lt less; typedef cds::atomicity::item_counter item_counter;