Removed redundant spaces
[libcds.git] / cds / container / skip_list_set_nogc.h
index 4c6695779c245cbcbef7f76e05a72b8651a13b44..5f7636156fcee3418579e3db88c7c9f6a0d32534 100644 (file)
@@ -1,10 +1,38 @@
-//$$CDS-header$$
+/*
+    This file is a part of libcds - Concurrent Data Structures library
 
-#ifndef __CDS_CONTAINER_SKIP_LIST_SET_NOGC_H
-#define __CDS_CONTAINER_SKIP_LIST_SET_NOGC_H
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    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_SKIP_LIST_SET_NOGC_H
+#define CDSLIB_CONTAINER_SKIP_LIST_SET_NOGC_H
 
 #include <cds/intrusive/skip_list_nogc.h>
-#include <cds/container/skip_list_base.h>
+#include <cds/container/details/skip_list_base.h>
 #include <cds/details/binary_functor_wrapper.h>
 #include <cds/gc/nogc.h>
 #include <cds/details/allocator.h>
@@ -28,7 +56,7 @@ namespace cds { namespace container {
         {
             typedef cds::gc::nogc   gc;
             typedef T               value_type;
-            typedef Traits          type_traits;
+            typedef Traits          traits;
 
             typedef cds::intrusive::skip_list::node< gc >   intrusive_node_type;
             struct node_type: public intrusive_node_type
@@ -51,7 +79,6 @@ namespace cds { namespace container {
                     }
                 }
 
-#       ifdef CDS_EMPLACE_SUPPORT
                 template <typename Q, typename... Args>
                 node_type( unsigned int nHeight, atomic_ptr * pTower, Q&& q, Args&&... args )
                     : m_Value( std::forward<Q>(q), std::forward<Args>(args)... )
@@ -61,13 +88,11 @@ namespace cds { namespace container {
                         base_class::make_tower( nHeight, pTower );
                     }
                 }
-#       endif
 
-            private:
-                node_type() ;   // no default ctor
+                node_type() = delete;   // no default ctor
             };
 
-            typedef skip_list::details::node_allocator< node_type, type_traits> node_allocator;
+            typedef skip_list::details::node_allocator< node_type, traits> node_allocator;
 
             struct node_deallocator {
                 void operator ()( node_type * pNode )
@@ -78,8 +103,8 @@ namespace cds { namespace container {
 
             typedef skip_list::details::dummy_node_builder<intrusive_node_type> dummy_node_builder;
 
-            typedef typename type_traits::key_accessor key_accessor;
-            typedef typename opt::details::make_comparator< value_type, type_traits >::type key_comparator;
+            typedef typename traits::key_accessor key_accessor;
+            typedef typename opt::details::make_comparator< value_type, traits >::type key_comparator;
 
             /*
             template <typename Less>
@@ -89,7 +114,7 @@ namespace cds { namespace container {
             */
 
             typedef typename cds::intrusive::skip_list::make_traits<
-                cds::opt::type_traits< type_traits >
+                cds::opt::type_traits< traits >
                 ,cds::intrusive::opt::hook< intrusive::skip_list::base_hook< cds::opt::gc< gc > > >
                 ,cds::intrusive::opt::disposer< node_deallocator >
                 ,cds::intrusive::skip_list::internal_node_builder< dummy_node_builder >
@@ -111,7 +136,7 @@ namespace cds { namespace container {
 
         Template arguments:
         - \p T - type to be stored in the list.
-        - \p Traits - type traits. See skip_list::type_traits for explanation.
+        - \p Traits - type traits. See skip_list::traits for explanation.
 
         It is possible to declare option-based list with cds::container::skip_list::make_traits metafunction istead of \p Traits template
         argument. \p Options template arguments of cds::container::skip_list::make_traits metafunction are:
@@ -131,7 +156,7 @@ namespace cds { namespace container {
     template <
         typename T,
 #ifdef CDS_DOXYGEN_INVOKED
-        class Traits = skip_list::type_traits
+        class Traits = skip_list::traits
 #else
         class Traits
 #endif
@@ -171,32 +196,17 @@ namespace cds { namespace container {
         >::type     key_accessor;
 
         typedef std::unique_ptr< node_type, typename maker::node_deallocator >    scoped_node_ptr;
-
-#   ifndef CDS_CXX11_LAMBDA_SUPPORT
-        struct ensure_functor
-        {
-            node_type * pNode;
-            void operator ()( bool bNew, node_type& node, node_type& )
-            {
-                pNode = &node;
-            }
-        };
-
-        struct find_functor
-        {
-            node_type * pNode;
-
-            template <typename Q>
-            void operator ()( node_type& node, Q& )
-            {
-                pNode = &node;
-            }
-        };
-#   endif
         //@endcond
 
     public:
-        /// Iterator type
+    ///@name Forward iterators
+    //@{
+        /// Forward ordered iterator
+        /**
+            The forward iterator for a split-list has some features:
+            - it has no post-increment operator
+            - it depends on iterator of underlying \p OrderedList
+        */
         typedef skip_list::details::iterator< typename base_class::iterator >  iterator;
 
         /// Const iterator type
@@ -205,38 +215,38 @@ namespace cds { namespace container {
         /// Returns a forward iterator addressing the first element in a set
         iterator begin()
         {
-            return iterator( base_class::begin() );
+            return iterator( base_class::begin());
         }
 
         /// Returns a forward const iterator addressing the first element in a set
-        //@{
         const_iterator begin() const
         {
-            return const_iterator( base_class::begin() );
+            return const_iterator( base_class::begin());
         }
-        const_iterator cbegin()
+
+        /// Returns a forward const iterator addressing the first element in a set
+        const_iterator cbegin() const
         {
-            return const_iterator( base_class::cbegin() );
+            return const_iterator( base_class::cbegin());
         }
-        //@}
 
         /// Returns a forward iterator that addresses the location succeeding the last element in a set.
         iterator end()
         {
-            return iterator( base_class::end() );
+            return iterator( base_class::end());
         }
 
         /// Returns a forward const iterator that addresses the location succeeding the last element in a set.
-        //@{
         const_iterator end() const
         {
-            return const_iterator( base_class::end() );
+            return const_iterator( base_class::end());
         }
-        const_iterator cend()
+        /// Returns a forward const iterator that addresses the location succeeding the last element in a set.
+        const_iterator cend() const
         {
-            return const_iterator( base_class::cend() );
+            return const_iterator( base_class::cend());
         }
-        //@}
+    //@}
 
     protected:
         //@cond
@@ -268,96 +278,107 @@ namespace cds { namespace container {
         iterator insert( const Q& val )
         {
             scoped_node_ptr sp( node_allocator().New( base_class::random_level(), val ));
-            if ( base_class::insert( *sp.get() )) {
-                return node_to_iterator( sp.release() );
+            if ( base_class::insert( *sp.get())) {
+                return node_to_iterator( sp.release());
             }
             return end();
         }
 
-#ifdef CDS_EMPLACE_SUPPORT
         /// Inserts data of type \ref value_type constructed with <tt>std::forward<Args>(args)...</tt>
         /**
             Return an iterator pointing to inserted item if success \ref end() otherwise
-
-            This function is available only for compiler that supports
-            variadic template and move semantics
         */
         template <typename... Args>
         iterator emplace( Args&&... args )
         {
             scoped_node_ptr sp( node_allocator().New( base_class::random_level(), std::forward<Args>(args)... ));
-            if ( base_class::insert( *sp.get() )) {
-                return node_to_iterator( sp.release() );
+            if ( base_class::insert( *sp.get())) {
+                return node_to_iterator( sp.release());
             }
             return end();
         }
-#endif
 
-        /// Ensures that the item \p val exists in the set
+        /// Updates the item
         /**
-            The operation inserts new item if the key \p val is not found in the set.
-            Otherwise, the function returns an iterator that points to item found.
+            The operation inserts new item if \p val is not found in the set and \p bInsert is \p true.
+            Otherwise, if that key exists, the function returns an iterator that points to item found.
 
-            Returns <tt> std::pair<iterator, bool>  </tt> where \p first is an iterator pointing to
-            item found or inserted, \p second is true if new item has been added or \p false if the item
+            Returns <tt> std::pair<iterator, bool> </tt> where \p first is an iterator pointing to
+            item found or inserted or \p end() if \p val is not found and \p bInsert is \p false,
+            \p second is \p true if new item has been added or \p false if the item
             already is in the set.
         */
         template <typename Q>
-        std::pair<iterator, bool> ensure( const Q& val )
+        std::pair<iterator, bool> update( const Q& val, bool bInsert = true )
         {
             scoped_node_ptr sp( node_allocator().New( base_class::random_level(), val ));
-#       ifdef CDS_CXX11_LAMBDA_SUPPORT
             node_type * pNode;
-            std::pair<bool, bool> bRes = base_class::ensure( *sp, [&pNode](bool, node_type& item, node_type&) { pNode = &item; } );
+            std::pair<bool, bool> bRes = base_class::update( *sp, [&pNode](bool, node_type& item, node_type&) { pNode = &item; }, bInsert );
             if ( bRes.first && bRes.second )
                 sp.release();
+            else if ( !bRes.first )
+                return std::make_pair( end(), false );
             assert( pNode );
             return std::make_pair( node_to_iterator( pNode ), bRes.second );
-#       else
-            ensure_functor f;
-            std::pair<bool, bool> bRes = base_class::ensure( *sp, cds::ref(f) );
-            if ( bRes.first && bRes.second )
-                sp.release();
-            assert( f.pNode );
-            return std::make_pair( node_to_iterator( f.pNode ), bRes.second );
-#       endif
         }
+        //@cond
+        template <typename Q>
+        CDS_DEPRECATED("ensure() is deprecated, use update()")
+        std::pair<iterator, bool> ensure( const Q& val )
+        {
+            return update( val, true );
+        }
+        //@endcond
 
-        /// Searches \p key
-        /** \anchor cds_nonintrusive_SkipListSet_nogc_find_val
-
+        /// Checks whether the set contains \p key
+        /**
             The function searches the item with key equal to \p key
-            and returns an iterator pointed to item found if the key is found,
-            and \ref end() otherwise
+            and returns an iterator to item found or \p end() if the key is not fund
         */
         template <typename Q>
-        iterator find( Q const& key ) const
+        iterator contains( Q const& key ) const
         {
-            node_type * pNode = base_class::find( key );
+            node_type * pNode = base_class::contains( key );
             if ( pNode )
                 return node_to_iterator( pNode );
             return base_class::nonconst_end();
         }
+        //@cond
+        template <typename Q>
+        CDS_DEPRECATED("deprecated, use contains()")
+        iterator find( Q const& key ) const
+        {
+            return contains( key );
+        }
+        //@edncond
 
-        /// Finds the key \p val using \p pred predicate for searching
+        /// Checks whether the set contains \p key using \p pred predicate for searching
         /**
-            The function is an analog of \ref cds_nonintrusive_SkipListSet_nogc_find_val "find(Q const&)"
-            but \p pred is used for key comparing.
+            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 Less>
-        iterator find_with( Q const& key, Less pred ) const
+        iterator contains( Q const& key, Less pred ) const
         {
-            node_type * pNode = base_class::find_with( key, cds::details::predicate_wrapper< node_type, Less, key_accessor>() );
+            CDS_UNUSED( pred );
+            node_type * pNode = base_class::contains( key, cds::details::predicate_wrapper< node_type, Less, key_accessor>());
             if ( pNode )
                 return node_to_iterator( pNode );
             return base_class::nonconst_end();
         }
+        //@cond
+        template <typename Q, typename Less>
+        CDS_DEPRECATED("deprecated, use contains()")
+        iterator find_with( Q const& key, Less pred ) const
+        {
+            return contains( key, pred );
+        }
+        //@endcond
 
         /// Gets minimum key from the set
         /**
-            If the set is empty the function returns \p NULL
+            If the set is empty the function returns \p nullptr
         */
         value_type * get_min() const
         {
@@ -367,7 +388,7 @@ namespace cds { namespace container {
 
         /// Gets maximum key from the set
         /**
-            The function returns \p NULL if the set is empty
+            The function returns \p nullptr if the set is empty
         */
         value_type * get_max() const
         {
@@ -420,4 +441,4 @@ namespace cds { namespace container {
 
 }} // cds::container
 
-#endif // ifndef __CDS_CONTAINER_SKIP_LIST_SET_NOGC_H
+#endif // ifndef CDSLIB_CONTAINER_SKIP_LIST_SET_NOGC_H