fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / libcds-2.3.2 / cds / container / cuckoo_set.h
diff --git a/gdax-orderbook-hpp/demo/dependencies/libcds-2.3.2/cds/container/cuckoo_set.h b/gdax-orderbook-hpp/demo/dependencies/libcds-2.3.2/cds/container/cuckoo_set.h
new file mode 100644 (file)
index 0000000..d29bf8d
--- /dev/null
@@ -0,0 +1,850 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef CDSLIB_CONTAINER_CUCKOO_SET_H
+#define CDSLIB_CONTAINER_CUCKOO_SET_H
+
+#include <cds/container/details/cuckoo_base.h>
+#include <cds/details/binary_functor_wrapper.h>
+
+namespace cds { namespace container {
+
+    //@cond
+    namespace details {
+        template <typename T, typename Traits>
+        struct make_cuckoo_set
+        {
+            typedef T value_type;
+            typedef Traits original_traits;
+            typedef typename original_traits::probeset_type probeset_type;
+            static bool const store_hash = original_traits::store_hash;
+            static unsigned int const store_hash_count = store_hash ? ((unsigned int) std::tuple_size< typename original_traits::hash::hash_tuple_type >::value) : 0;
+
+            struct node_type: public intrusive::cuckoo::node<probeset_type, store_hash_count>
+            {
+                value_type  m_val;
+
+                template <typename Q>
+                node_type( Q const& v )
+                    : m_val(v)
+                {}
+
+                template <typename... Args>
+                node_type( Args&&... args )
+                    : m_val( std::forward<Args>(args)...)
+                {}
+            };
+
+            struct value_accessor {
+                value_type const& operator()( node_type const& node ) const
+                {
+                    return node.m_val;
+                }
+            };
+
+            template <typename Pred, typename ReturnValue>
+            using predicate_wrapper = cds::details::binary_functor_wrapper< ReturnValue, Pred, node_type, value_accessor >;
+
+            struct intrusive_traits: public original_traits
+            {
+                typedef intrusive::cuckoo::base_hook<
+                    cds::intrusive::cuckoo::probeset_type< probeset_type >
+                    ,cds::intrusive::cuckoo::store_hash< store_hash_count >
+                >  hook;
+
+                typedef cds::intrusive::cuckoo::traits::disposer   disposer;
+
+                typedef typename std::conditional<
+                    std::is_same< typename original_traits::equal_to, opt::none >::value
+                    , opt::none
+                    , predicate_wrapper< typename original_traits::equal_to, bool >
+                >::type equal_to;
+
+                typedef typename std::conditional<
+                    std::is_same< typename original_traits::compare, opt::none >::value
+                    , opt::none
+                    , predicate_wrapper< typename original_traits::compare, int >
+                >::type compare;
+
+                typedef typename std::conditional<
+                    std::is_same< typename original_traits::less, opt::none >::value
+                    ,opt::none
+                    ,predicate_wrapper< typename original_traits::less, bool >
+                >::type less;
+
+                typedef opt::details::hash_list_wrapper< typename original_traits::hash, node_type, value_accessor >    hash;
+            };
+
+            typedef intrusive::CuckooSet< node_type, intrusive_traits > type;
+        };
+    } // namespace details
+    //@endcond
+
+    /// Cuckoo hash set
+    /** @ingroup cds_nonintrusive_set
+
+        Source
+            - [2007] M.Herlihy, N.Shavit, M.Tzafrir "Concurrent Cuckoo Hashing. Technical report"
+            - [2008] Maurice Herlihy, Nir Shavit "The Art of Multiprocessor Programming"
+
+        <b>About Cuckoo hashing</b>
+
+            [From "The Art of Multiprocessor Programming"]
+            <a href="https://en.wikipedia.org/wiki/Cuckoo_hashing">Cuckoo hashing</a> is a hashing algorithm in which a newly added item displaces any earlier item
+            occupying the same slot. For brevity, a table is a k-entry array of items. For a hash set f size
+            N = 2k we use a two-entry array of tables, and two independent hash functions,
+            <tt> h0, h1: KeyRange -> 0,...,k-1</tt>
+            mapping the set of possible keys to entries in he array. To test whether a value \p x is in the set,
+            <tt>find(x)</tt> tests whether either <tt>table[0][h0(x)]</tt> or <tt>table[1][h1(x)]</tt> is
+            equal to \p x. Similarly, <tt>erase(x)</tt>checks whether \p x is in either <tt>table[0][h0(x)]</tt>
+            or <tt>table[1][h1(x)]</tt>, ad removes it if found.
+
+            The <tt>insert(x)</tt> successively "kicks out" conflicting items until every key has a slot.
+            To add \p x, the method swaps \p x with \p y, the current occupant of <tt>table[0][h0(x)]</tt>.
+            If the prior value was \p nullptr, it is done. Otherwise, it swaps the newly nest-less value \p y
+            for the current occupant of <tt>table[1][h1(y)]</tt> in the same way. As before, if the prior value
+            was \p nullptr, it is done. Otherwise, the method continues swapping entries (alternating tables)
+            until it finds an empty slot. We might not find an empty slot, either because the table is full,
+            or because the sequence of displacement forms a cycle. We therefore need an upper limit on the
+            number of successive displacements we are willing to undertake. When this limit is exceeded,
+            we resize the hash table, choose new hash functions and start over.
+
+            For concurrent cuckoo hashing, rather than organizing the set as a two-dimensional table of
+            items, we use two-dimensional table of probe sets, where a probe set is a constant-sized set
+            of items with the same hash code. Each probe set holds at most \p PROBE_SIZE items, but the algorithm
+            tries to ensure that when the set is quiescent (i.e no method call in progress) each probe set
+            holds no more than <tt>THRESHOLD < PROBE_SET</tt> items. While method calls are in-flight, a probe
+            set may temporarily hold more than \p THRESHOLD but never more than \p PROBE_SET items.
+
+            In current implementation, a probe set can be defined either as a (single-linked) list
+            or as a fixed-sized vector, optionally ordered.
+
+            In description above two-table cuckoo hashing (<tt>k = 2</tt>) has been considered.
+            We can generalize this approach for <tt>k >= 2</tt> when we have \p k hash functions
+            <tt>h[0], ... h[k-1]</tt> and \p k tables <tt>table[0], ... table[k-1]</tt>.
+
+            The search in probe set is linear, the complexity is <tt> O(PROBE_SET) </tt>.
+            The probe set may be ordered or not. Ordered probe set can be a little better since
+            the average search complexity is <tt>O(PROBE_SET/2)</tt>.
+            However, the overhead of sorting can eliminate a gain of ordered search.
+
+            The probe set is ordered if \p compare or \p less is specified in \p Traits
+            template parameter. Otherwise, the probe set is unordered and \p Traits must contain
+            \p equal_to predicate.
+
+        Template arguments:
+        - \p T - the type stored in the set.
+        - \p Traits - type traits. See cuckoo::traits for explanation.
+            It is possible to declare option-based set with cuckoo::make_traits metafunction result as \p Traits template argument.
+
+        <b>Examples</b>
+
+        Cuckoo-set with list-based unordered probe set and storing hash values
+        \code
+        #include <cds/container/cuckoo_set.h>
+
+        // Data stored in cuckoo set
+        struct my_data
+        {
+            // key field
+            std::string     strKey;
+
+            // other data
+            // ...
+        };
+
+        // Provide equal_to functor for my_data since we will use unordered probe-set
+        struct my_data_equal_to {
+            bool operator()( const my_data& d1, const my_data& d2 ) const
+            {
+                return d1.strKey.compare( d2.strKey ) == 0;
+            }
+
+            bool operator()( const my_data& d, const std::string& s ) const
+            {
+                return d.strKey.compare(s) == 0;
+            }
+
+            bool operator()( const std::string& s, const my_data& d ) const
+            {
+                return s.compare( d.strKey ) == 0;
+            }
+        };
+
+        // Provide two hash functor for my_data
+        struct hash1 {
+            size_t operator()(std::string const& s) const
+            {
+                return cds::opt::v::hash<std::string>( s );
+            }
+            size_t operator()( my_data const& d ) const
+            {
+                return (*this)( d.strKey );
+            }
+        };
+
+        struct hash2: private hash1 {
+            size_t operator()(std::string const& s) const
+            {
+                size_t h = ~( hash1::operator()(s));
+                return ~h + 0x9e3779b9 + (h << 6) + (h >> 2);
+            }
+            size_t operator()( my_data const& d ) const
+            {
+                return (*this)( d.strKey );
+            }
+        };
+
+        // Declare type traits
+        struct my_traits: public cds::container::cuckoo::traits
+        {
+            typedef my_data_equa_to equal_to;
+            typedef std::tuple< hash1, hash2 >  hash;
+
+            static bool const store_hash = true;
+        };
+
+        // Declare CuckooSet type
+        typedef cds::container::CuckooSet< my_data, my_traits > my_cuckoo_set;
+
+        // Equal option-based declaration
+        typedef cds::container::CuckooSet< my_data,
+            cds::container::cuckoo::make_traits<
+                cds::opt::hash< std::tuple< hash1, hash2 > >
+                ,cds::opt::equal_to< my_data_equal_to >
+                ,cds::container::cuckoo::store_hash< true >
+            >::type
+        > opt_cuckoo_set;
+        \endcode
+
+        If we provide \p compare function instead of \p equal_to for \p my_data
+        we get as a result a cuckoo set with ordered probe set that may improve
+        performance.
+        Example for ordered vector-based probe-set:
+
+        \code
+        #include <cds/container/cuckoo_set.h>
+
+        // Data stored in cuckoo set
+        struct my_data
+        {
+            // key field
+            std::string     strKey;
+
+            // other data
+            // ...
+        };
+
+        // Provide compare functor for my_data since we want to use ordered probe-set
+        struct my_data_compare {
+            int operator()( const my_data& d1, const my_data& d2 ) const
+            {
+                return d1.strKey.compare( d2.strKey );
+            }
+
+            int operator()( const my_data& d, const std::string& s ) const
+            {
+                return d.strKey.compare(s);
+            }
+
+            int operator()( const std::string& s, const my_data& d ) const
+            {
+                return s.compare( d.strKey );
+            }
+        };
+
+        // Provide two hash functor for my_data
+        struct hash1 {
+            size_t operator()(std::string const& s) const
+            {
+                return cds::opt::v::hash<std::string>( s );
+            }
+            size_t operator()( my_data const& d ) const
+            {
+                return (*this)( d.strKey );
+            }
+        };
+
+        struct hash2: private hash1 {
+            size_t operator()(std::string const& s) const
+            {
+                size_t h = ~( hash1::operator()(s));
+                return ~h + 0x9e3779b9 + (h << 6) + (h >> 2);
+            }
+            size_t operator()( my_data const& d ) const
+            {
+                return (*this)( d.strKey );
+            }
+        };
+
+        // Declare type traits
+        // We use a vector of capacity 4 as probe-set container and store hash values in the node
+        struct my_traits: public cds::container::cuckoo::traits
+        {
+            typedef my_data_compare compare;
+            typedef std::tuple< hash1, hash2 >  hash;
+            typedef cds::container::cuckoo::vector<4> probeset_type;
+
+            static bool const store_hash = true;
+        };
+
+        // Declare CuckooSet type
+        typedef cds::container::CuckooSet< my_data, my_traits > my_cuckoo_set;
+
+        // Equal option-based declaration
+        typedef cds::container::CuckooSet< my_data,
+            cds::container::cuckoo::make_traits<
+                cds::opt::hash< std::tuple< hash1, hash2 > >
+                ,cds::opt::compare< my_data_compare >
+                ,cds::container::cuckoo::probeset_type< cds::container::cuckoo::vector<4> >
+                ,cds::container::cuckoo::store_hash< true >
+            >::type
+        > opt_cuckoo_set;
+        \endcode
+
+    */
+    template <typename T, typename Traits = cuckoo::traits>
+    class CuckooSet:
+#ifdef CDS_DOXYGEN_INVOKED
+        protected intrusive::CuckooSet<T, Traits>
+#else
+        protected details::make_cuckoo_set<T, Traits>::type
+#endif
+    {
+        //@cond
+        typedef details::make_cuckoo_set<T, Traits> maker;
+        typedef typename maker::type  base_class;
+        //@endcond
+
+    public:
+        typedef T       value_type  ;   ///< value type stored in the container
+        typedef Traits  traits     ;   ///< traits
+
+        typedef typename traits::hash                 hash;   ///< hash functor tuple wrapped for internal use
+        typedef typename base_class::hash_tuple_type  hash_tuple_type;   ///< Type of hash tuple
+
+        typedef typename base_class::mutex_policy mutex_policy; ///< Concurrent access policy, see cuckoo::traits::mutex_policy
+        typedef typename base_class::stat         stat;         ///< internal statistics type
+
+
+        static bool const c_isSorted = base_class::c_isSorted; ///< whether the probe set should be ordered
+        static size_t const c_nArity = base_class::c_nArity;   ///< the arity of cuckoo hashing: the number of hash functors provided; minimum 2.
+
+        typedef typename base_class::key_equal_to key_equal_to; ///< Key equality functor; used only for unordered probe-set
+
+        typedef typename base_class::key_comparator  key_comparator; ///< key comparing functor based on \p Traits::compare and \p Traits::less option setter. Used only for ordered probe set
+
+        typedef typename base_class::allocator     allocator; ///< allocator type used for internal bucket table allocations
+
+        /// Node allocator type
+        typedef typename std::conditional<
+            std::is_same< typename traits::node_allocator, opt::none >::value,
+            allocator,
+            typename traits::node_allocator
+        >::type node_allocator;
+
+        /// item counter type
+        typedef typename traits::item_counter  item_counter;
+
+    protected:
+        //@cond
+        typedef typename base_class::value_type         node_type;
+        typedef cds::details::Allocator< node_type, node_allocator >    cxx_node_allocator;
+        //@endcond
+
+    public:
+        static unsigned int const   c_nDefaultProbesetSize = base_class::c_nDefaultProbesetSize; ///< default probeset size
+        static size_t const         c_nDefaultInitialSize = base_class::c_nDefaultInitialSize;   ///< default initial size
+        static unsigned int const   c_nRelocateLimit = base_class::c_nRelocateLimit;             ///< Count of attempts to relocate before giving up
+
+    protected:
+        //@cond
+        template <typename Q>
+        static node_type * alloc_node( Q const& v )
+        {
+            return cxx_node_allocator().New( v );
+        }
+        template <typename... Args>
+        static node_type * alloc_node( Args&&... args )
+        {
+            return cxx_node_allocator().MoveNew( std::forward<Args>(args)... );
+        }
+
+        static void free_node( node_type * pNode )
+        {
+            cxx_node_allocator().Delete( pNode );
+        }
+        //@endcond
+
+    protected:
+        //@cond
+        struct node_disposer {
+            void operator()( node_type * pNode )
+            {
+                free_node( pNode );
+            }
+        };
+
+        typedef std::unique_ptr< node_type, node_disposer >     scoped_node_ptr;
+
+        //@endcond
+
+    public:
+        /// Default constructor
+        /**
+            Initial size = \ref c_nDefaultInitialSize
+
+            Probe set size:
+            - \ref c_nDefaultProbesetSize if \p probeset_type is \p cuckoo::list
+            - \p Capacity if \p probeset_type is <tt> cuckoo::vector<Capacity> </tt>
+
+            Probe set threshold = probe set size - 1
+        */
+        CuckooSet()
+        {}
+
+        /// Constructs the set object with given probe set size and threshold
+        /**
+            If probe set type is <tt> cuckoo::vector<Capacity> </tt> vector
+            then \p nProbesetSize should be equal to vector's \p Capacity.
+        */
+        CuckooSet(
+            size_t nInitialSize                 ///< Initial set size; if 0 - use default initial size \ref c_nDefaultInitialSize
+            , unsigned int nProbesetSize        ///< probe set size
+            , unsigned int nProbesetThreshold = 0  ///< probe set threshold, <tt>nProbesetThreshold < nProbesetSize</tt>. If 0, nProbesetThreshold = nProbesetSize - 1
+        )
+        : base_class( nInitialSize, nProbesetSize, nProbesetThreshold )
+        {}
+
+        /// Constructs the set object with given hash functor tuple
+        /**
+            The probe set size and threshold are set as default, see CuckooSet()
+        */
+        CuckooSet(
+            hash_tuple_type const& h    ///< hash functor tuple of type <tt>std::tuple<H1, H2, ... Hn></tt> where <tt> n == \ref c_nArity </tt>
+        )
+        : base_class( h )
+        {}
+
+        /// Constructs the set object with given probe set properties and hash functor tuple
+        /**
+            If probe set type is <tt> cuckoo::vector<Capacity> </tt> vector
+            then \p nProbesetSize should be equal to vector's \p Capacity.
+        */
+        CuckooSet(
+            size_t nInitialSize                 ///< Initial set size; if 0 - use default initial size \ref c_nDefaultInitialSize
+            , unsigned int nProbesetSize        ///< probe set size
+            , unsigned int nProbesetThreshold   ///< probe set threshold, <tt>nProbesetThreshold < nProbesetSize</tt>. If 0, nProbesetThreshold = nProbesetSize - 1
+            , hash_tuple_type const& h    ///< hash functor tuple of type <tt>std::tuple<H1, H2, ... Hn></tt> where <tt> n == \ref c_nArity </tt>
+        )
+        : base_class( nInitialSize, nProbesetSize, nProbesetThreshold, h )
+        {}
+
+        /// Constructs the set object with given hash functor tuple (move semantics)
+        /**
+            The probe set size and threshold are set as default, see CuckooSet()
+        */
+        CuckooSet(
+            hash_tuple_type&& h     ///< hash functor tuple of type <tt>std::tuple<H1, H2, ... Hn></tt> where <tt> n == \ref c_nArity </tt>
+        )
+        : base_class( std::forward<hash_tuple_type>(h))
+        {}
+
+        /// Constructs the set object with given probe set properties and hash functor tuple (move semantics)
+        /**
+            If probe set type is <tt> cuckoo::vector<Capacity> </tt> vector
+            then \p nProbesetSize should be equal to vector's \p Capacity.
+        */
+        CuckooSet(
+            size_t nInitialSize                 ///< Initial set size; if 0 - use default initial size \ref c_nDefaultInitialSize
+            , unsigned int nProbesetSize        ///< probe set size
+            , unsigned int nProbesetThreshold   ///< probe set threshold, <tt>nProbesetThreshold < nProbesetSize</tt>. If 0, nProbesetThreshold = nProbesetSize - 1
+            , hash_tuple_type&& h    ///< hash functor tuple of type <tt>std::tuple<H1, H2, ... Hn></tt> where <tt> n == \ref c_nArity </tt>
+        )
+        : base_class( nInitialSize, nProbesetSize, nProbesetThreshold, std::forward<hash_tuple_type>(h))
+        {}
+
+        /// Destructor clears the set
+        ~CuckooSet()
+        {
+            clear();
+        }
+
+    public:
+        /// Inserts new node
+        /**
+            The function creates a node with copy of \p val value
+            and then inserts the node created into the set.
+
+            The type \p Q should contain as minimum the complete key for the node.
+            The object of \ref value_type should be constructible from a value of type \p Q.
+            In trivial case, \p Q is equal to \ref value_type.
+
+            Returns \p true if \p val is inserted into the set, \p false otherwise.
+        */
+        template <typename Q>
+        bool insert( Q const& val )
+        {
+            return insert( val, []( value_type& ) {} );
+        }
+
+        /// Inserts new node
+        /**
+            The function allows to split creating of new item into two part:
+            - create item with key only
+            - insert new item into the set
+            - if inserting is success, calls \p f functor to initialize value-field of new item .
+
+            The functor signature is:
+            \code
+                void func( value_type& item );
+            \endcode
+            where \p item is the item inserted.
+
+            The type \p Q can differ from \ref value_type of items storing in the set.
+            Therefore, the \p value_type should be constructible from type \p Q.
+
+            The user-defined functor is called only if the inserting is success.
+        */
+        template <typename Q, typename Func>
+        bool insert( Q const& val, Func f )
+        {
+            scoped_node_ptr pNode( alloc_node( val ));
+            if ( base_class::insert( *pNode, [&f]( node_type& node ) { f( node.m_val ); } )) {
+                pNode.release();
+                return true;
+            }
+            return false;
+        }
+
+        /// Inserts data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
+        /**
+            Returns \p true if inserting successful, \p false otherwise.
+        */
+        template <typename... Args>
+        bool emplace( Args&&... args )
+        {
+            scoped_node_ptr pNode( alloc_node( std::forward<Args>(args)... ));
+            if ( base_class::insert( *pNode )) {
+                pNode.release();
+                return true;
+            }
+            return false;
+        }
+
+        /// Updates the node
+        /**
+            The operation performs inserting or changing data with lock-free manner.
+
+            If the item \p val is not found in the set, then \p val is inserted into the set
+            iff \p bAllowInsert is \p true.
+            Otherwise, the functor \p func is called with item found.
+            The functor \p func signature is:
+            \code
+                struct my_functor {
+                    void operator()( bool bNew, value_type& item, const Q& val );
+                };
+            \endcode
+            with arguments:
+            - \p bNew - \p true if the item has been inserted, \p false otherwise
+            - \p item - item of the set
+            - \p val - argument \p val passed into the \p %update() function
+            If new item has been inserted (i.e. \p bNew is \p true) then \p item and \p val arguments
+            refer to the same thing.
+
+            Returns std::pair<bool, bool> where \p first is \p true if operation is successful,
+            i.e. the node has been inserted or updated,
+            \p second is \p true if new item has been added or \p false if the item with \p key
+            already exists.
+        */
+        template <typename Q, typename Func>
+        std::pair<bool, bool> update( Q const& val, Func func, bool bAllowInsert = true )
+        {
+            scoped_node_ptr pNode( alloc_node( val ));
+            std::pair<bool, bool> res = base_class::update( *pNode,
+                [&val,&func](bool bNew, node_type& item, node_type const& ){ func( bNew, item.m_val, val ); },
+                bAllowInsert
+            );
+            if ( res.first && res.second )
+                pNode.release();
+            return res;
+        }
+        //@cond
+        template <typename Q, typename Func>
+        CDS_DEPRECATED("ensure() is deprecated, use update()")
+        std::pair<bool, bool> ensure( Q const& val, Func func )
+        {
+            return update( val, func, true );
+        }
+        //@endcond
+
+        /// Delete \p key from the set
+        /** \anchor cds_nonintrusive_CuckooSet_erase
+
+            Since the key of set's item type \ref value_type is not explicitly specified,
+            template parameter \p Q defines the key type searching in the list.
+            The set 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
+        */
+        template <typename Q>
+        bool erase( Q const& key )
+        {
+            node_type * pNode = base_class::erase( key );
+            if ( pNode ) {
+                free_node( pNode );
+                return true;
+            }
+            return false;
+        }
+
+        /// Deletes the item from the list using \p pred predicate for searching
+        /**
+            The function is an analog of \ref cds_nonintrusive_CuckooSet_erase "erase(Q const&)"
+            but \p pred is used for key comparing.
+            If cuckoo set is ordered, then \p Predicate should have the interface and semantics like \p std::less.
+            If cuckoo set is unordered, then \p Predicate should have the interface and semantics like \p std::equal_to.
+            \p Predicate must imply the same element order as the comparator used for building the set.
+        */
+        template <typename Q, typename Predicate>
+        bool erase_with( Q const& key, Predicate pred )
+        {
+            CDS_UNUSED( pred );
+            node_type * pNode = base_class::erase_with( key, typename maker::template predicate_wrapper<Predicate, bool>());
+            if ( pNode ) {
+                free_node( pNode );
+                return true;
+            }
+            return false;
+        }
+
+        /// Delete \p key from the set
+        /** \anchor cds_nonintrusive_CuckooSet_erase_func
+
+            The function searches an item with key \p key, calls \p f functor
+            and deletes the item. If \p key is not found, the functor is not called.
+
+            The functor \p Func interface is:
+            \code
+            struct functor {
+                void operator()(value_type const& val);
+            };
+            \endcode
+
+            Return \p true if key is found and deleted, \p false otherwise
+        */
+        template <typename Q, typename Func>
+        bool erase( Q const& key, Func f )
+        {
+            node_type * pNode = base_class::erase( key );
+            if ( pNode ) {
+                f( pNode->m_val );
+                free_node( pNode );
+                return true;
+            }
+            return false;
+        }
+
+        /// Deletes the item from the list using \p pred predicate for searching
+        /**
+            The function is an analog of \ref cds_nonintrusive_CuckooSet_erase_func "erase(Q const&, Func)"
+            but \p pred is used for key comparing.
+            If you use ordered cuckoo set, then \p Predicate should have the interface and semantics like \p std::less.
+            If you use unordered cuckoo set, then \p Predicate should have the interface and semantics like \p std::equal_to.
+            \p Predicate must imply the same element order as the comparator used for building the set.
+        */
+        template <typename Q, typename Predicate, typename Func>
+        bool erase_with( Q const& key, Predicate pred, Func f )
+        {
+            CDS_UNUSED( pred );
+            node_type * pNode = base_class::erase_with( key, typename maker::template predicate_wrapper<Predicate, bool>());
+            if ( pNode ) {
+                f( pNode->m_val );
+                free_node( pNode );
+                return true;
+            }
+            return false;
+        }
+
+        /// Find the key \p val
+        /** \anchor cds_nonintrusive_CuckooSet_find_func
+
+            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& val );
+            };
+            \endcode
+            where \p item is the item found, \p val is the <tt>find</tt> function argument.
+
+            The functor can change non-key fields of \p item.
+            The \p val argument is non-const since it can be used as \p f functor destination i.e., the functor
+            can modify both arguments.
+
+            The type \p Q can differ from \ref value_type of items storing in the container.
+            Therefore, the \p value_type should be comparable with type \p Q.
+
+            The function returns \p true if \p val is found, \p false otherwise.
+        */
+        template <typename Q, typename Func>
+        bool find( Q& val, Func f )
+        {
+            return base_class::find( val, [&f](node_type& item, Q& v) { f( item.m_val, v );});
+        }
+        //@cond
+        template <typename Q, typename Func>
+        bool find( Q const& val, Func f )
+        {
+            return base_class::find( val, [&f](node_type& item, Q const& v) { f( item.m_val, v );});
+        }
+        //@endcond
+
+        /// Find the key \p val using \p pred predicate for comparing
+        /**
+            The function is an analog of \ref cds_nonintrusive_CuckooSet_find_func "find(Q&, Func)"
+            but \p pred is used for key comparison.
+            If you use ordered cuckoo set, then \p Predicate should have the interface and semantics like \p std::less.
+            If you use unordered cuckoo set, then \p Predicate should have the interface and semantics like \p std::equal_to.
+            \p pred must imply the same element order as the comparator used for building the set.
+        */
+        template <typename Q, typename Predicate, typename Func>
+        bool find_with( Q& val, Predicate pred, Func f )
+        {
+            CDS_UNUSED( pred );
+            return base_class::find_with( val, typename maker::template predicate_wrapper<Predicate, bool>(),
+                [&f](node_type& item, Q& v) { f( item.m_val, v );});
+        }
+        //@cond
+        template <typename Q, typename Predicate, typename Func>
+        bool find_with( Q const& val, Predicate pred, Func f )
+        {
+            CDS_UNUSED( pred );
+            return base_class::find_with( val, typename maker::template predicate_wrapper<Predicate, bool>(),
+                [&f](node_type& item, Q const& v) { f( item.m_val, v );});
+        }
+        //@endcond
+
+        /// Checks whether the set contains \p key
+        /**
+            The function searches the item with key equal to \p key
+            and returns \p true if it is found, and \p false otherwise.
+        */
+        template <typename Q>
+        bool contains( Q const& key )
+        {
+            return base_class::find( key, [](node_type&, Q const&) {});
+        }
+        //@cond
+        template <typename Q>
+        CDS_DEPRECATED("the function is deprecated, use contains()")
+        bool find( Q const& key )
+        {
+            return contains( key );
+        }
+        //@endcond
+
+        /// Checks whether the set contains \p key using \p pred predicate for searching
+        /**
+            The function is similar to <tt>contains( key )</tt> but \p pred is used for key comparing.
+            \p Less functor has the interface like \p std::less.
+            \p Less must imply the same element order as the comparator used for building the set.
+        */
+        template <typename Q, typename Predicate>
+        bool contains( Q const& key, Predicate pred )
+        {
+            CDS_UNUSED( pred );
+            return base_class::find_with( key, typename maker::template predicate_wrapper<Predicate, bool>(), [](node_type&, Q const&) {});
+        }
+        //@cond
+        template <typename Q, typename Predicate>
+        CDS_DEPRECATED("the function is deprecated, use contains()")
+        bool find_with( Q const& key, Predicate pred )
+        {
+            return contains( key, pred );
+        }
+        //@endcond
+
+        /// Clears the set
+        /**
+            The function erases all items from the set.
+        */
+        void clear()
+        {
+            return base_class::clear_and_dispose( node_disposer());
+        }
+
+        /// Checks if the set is empty
+        /**
+            Emptiness is checked by item counting: if item count is zero then the set is empty.
+        */
+        bool empty() const
+        {
+            return base_class::empty();
+        }
+
+        /// Returns item count in the set
+        size_t size() const
+        {
+            return base_class::size();
+        }
+
+        /// Returns the size of hash table
+        /**
+            The hash table size is non-constant and can be increased via resizing.
+        */
+        size_t bucket_count() const
+        {
+            return base_class::bucket_count();
+        }
+
+        /// Returns lock array size
+        size_t lock_count() const
+        {
+            return base_class::lock_count();
+        }
+
+        /// Returns const reference to internal statistics
+        stat const& statistics() const
+        {
+            return base_class::statistics();
+        }
+
+        /// Returns const reference to mutex policy internal statistics
+        typename mutex_policy::statistics_type const& mutex_policy_statistics() const
+        {
+            return base_class::mutex_policy_statistics();
+        }
+    };
+
+}} // namespace cds::container
+
+#endif //#ifndef CDSLIB_CONTAINER_CUCKOO_SET_H