fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / libcds-2.3.2 / cds / container / mspriority_queue.h
diff --git a/gdax-orderbook-hpp/demo/dependencies/libcds-2.3.2/cds/container/mspriority_queue.h b/gdax-orderbook-hpp/demo/dependencies/libcds-2.3.2/cds/container/mspriority_queue.h
new file mode 100644 (file)
index 0000000..62c12cf
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+    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_MSPRIORITY_QUEUE_H
+#define CDSLIB_CONTAINER_MSPRIORITY_QUEUE_H
+
+#include <memory>
+#include <cds/container/details/base.h>
+#include <cds/intrusive/mspriority_queue.h>
+
+namespace cds { namespace container {
+
+    /// MSPriorityQueue related definitions
+    /** @ingroup cds_nonintrusive_helper
+    */
+    namespace mspriority_queue {
+
+#ifdef CDS_DOXYGEN_INVOKED
+        /// Synonym for \p cds::intrusive::mspriority_queue::stat
+        typedef cds::intrusive::mspriority_queue::stat<> stat;
+
+        /// Synonym for \p cds::intrusive::mspriority_queue::empty_stat
+        typedef cds::intrusive::mspriority_queue::empty_stat empty_stat;
+#else
+        using cds::intrusive::mspriority_queue::stat;
+        using cds::intrusive::mspriority_queue::empty_stat;
+#endif
+
+        /// MSPriorityQueue traits
+        /**
+            The traits for \p %cds::container::MSPriorityQueue is the same as for
+            \p cds::intrusive::MSPriorityQueue (see \p cds::intrusive::mspriority_queue::traits)
+            plus some additional properties.
+        */
+        struct traits: public cds::intrusive::mspriority_queue::traits
+        {
+            /// The allocator use to allocate memory for values
+            typedef CDS_DEFAULT_ALLOCATOR   allocator;
+
+            /// Move policy
+            /**
+                The move policy used in \p MSPriorityQueue::pop() function to move item's value.
+                Default is \p opt::v::assignment_move_policy.
+            */
+            typedef cds::opt::v::assignment_move_policy  move_policy;
+        };
+
+        /// Metafunction converting option list to traits
+        /**
+            \p Options are:
+            - \p opt::buffer - the buffer type for heap array. Possible type are: \p opt::v::initiaized_static_buffer, \p opt::v::initialized_dynamic_buffer.
+                Default is \p %opt::v::initialized_dynamic_buffer.
+                You may specify any type of values for the buffer since at instantiation time
+                the \p buffer::rebind member metafunction is called to change the type of values stored in the buffer.
+            - \p opt::compare - priority compare 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 priority compare. Default is \p std::less<T>.
+            - \p opt::lock_type - lock type. Default is \p cds::sync::spin.
+            - \p opt::back_off - back-off strategy. Default is \p cds::backoff::yield
+            - \p opt::allocator - allocator (like \p std::allocator) for the values of queue's items.
+                Default is \ref CDS_DEFAULT_ALLOCATOR
+            - \p opt::move_policy - policy for moving item's value. Default is \p opt::v::assignment_move_policy.
+                If the compiler supports move semantics it would be better to specify the move policy
+                based on the move semantics for type \p T.
+            - \p opt::stat - internal statistics. Available types: \p mspriority_queue::stat, \p mspriority_queue::empty_stat (the default, no overhead)
+            */
+        template <typename... Options>
+        struct make_traits {
+#   ifdef CDS_DOXYGEN_INVOKED
+            typedef implementation_defined type ;   ///< Metafunction result
+#   else
+            typedef typename cds::opt::make_options<
+                typename cds::opt::find_type_traits< traits, Options... >::type
+                ,Options...
+            >::type   type;
+#   endif
+        };
+    }   // namespace mspriority_queue
+
+    /// Michael & Scott array-based lock-based concurrent priority queue heap
+    /** @ingroup cds_nonintrusive_priority_queue
+        Source:
+            - [1996] G.Hunt, M.Michael, S. Parthasarathy, M.Scott
+                "An efficient algorithm for concurrent priority queue heaps"
+
+        \p %MSPriorityQueue augments the standard array-based heap data structure with
+        a mutual-exclusion lock on the heap's size and locks on each node in the heap.
+        Each node also has a tag that indicates whether
+        it is empty, valid, or in a transient state due to an update to the heap
+        by an inserting thread.
+        The algorithm allows concurrent insertions and deletions in opposite directions,
+        without risking deadlock and without the need for special server threads.
+        It also uses a "bit-reversal" technique to scatter accesses across the fringe
+        of the tree to reduce contention.
+        On large heaps the algorithm achieves significant performance improvements
+        over serialized single-lock algorithm, for various insertion/deletion
+        workloads. For small heaps it still performs well, but not as well as
+        single-lock algorithm.
+
+        Template parameters:
+        - \p T - type to be stored in the list. The priority is a part of \p T type.
+        - \p Traits - the traits. See \p mspriority_queue::traits for explanation.
+             It is possible to declare option-based queue with \p mspriority_queue::make_traits
+             metafunction instead of \p Traits template argument.
+    */
+    template <typename T, class Traits = mspriority_queue::traits >
+    class MSPriorityQueue: protected cds::intrusive::MSPriorityQueue< T, Traits >
+    {
+        //@cond
+        typedef cds::intrusive::MSPriorityQueue< T, Traits > base_class;
+        //@endcond
+    public:
+        typedef T           value_type  ;   ///< Value type stored in the queue
+        typedef Traits      traits      ;   ///< Traits template parameter
+
+        typedef typename base_class::key_comparator key_comparator; ///< priority comparing functor based on opt::compare and opt::less option setter.
+        typedef typename base_class::lock_type lock_type;   ///< heap's size lock type
+        typedef typename base_class::back_off  back_off ;   ///< Back-off strategy
+        typedef typename traits::stat          stat;        ///< internal statistics type, see \p intrusive::mspriority_queue::traits::stat
+        typedef typename base_class::item_counter  item_counter;///< Item counter type
+        typedef typename traits::allocator::template rebind<value_type>::other allocator_type; ///< Value allocator
+        typedef typename traits::move_policy   move_policy; ///< Move policy for type \p T
+
+    protected:
+        //@cond
+        typedef cds::details::Allocator< value_type, allocator_type >  cxx_allocator;
+
+        struct value_deleter {
+            void operator()( value_type * p ) const
+            {
+                cxx_allocator().Delete( p );
+            }
+        };
+        typedef std::unique_ptr<value_type, value_deleter> scoped_ptr;
+        //@endcond
+
+    public:
+        /// Constructs empty priority queue
+        /**
+            For \p cds::opt::v::initialized_static_buffer the \p nCapacity parameter is ignored.
+        */
+        MSPriorityQueue( size_t nCapacity )
+            : base_class( nCapacity )
+        {}
+
+        /// Clears priority queue and destructs the object
+        ~MSPriorityQueue()
+        {
+            clear();
+        }
+
+        /// Inserts an item into priority queue
+        /**
+            If the priority queue is full, the function returns \p false,
+            no item has been added.
+            Otherwise, the function inserts the copy of \p val into the heap
+            and returns \p true.
+
+            The function use copy constructor to create new heap item from \p val.
+        */
+        bool push( value_type const& val )
+        {
+            scoped_ptr pVal( cxx_allocator().New( val ));
+            if ( base_class::push( *(pVal.get()))) {
+                pVal.release();
+                return true;
+            }
+            return false;
+        }
+
+        /// Inserts an item into the queue using a functor
+        /**
+            \p Func is a functor called to create node.
+            The functor \p f takes one argument - a reference to a new node of type \ref value_type :
+            \code
+            cds::container::MSPriorityQueue< Foo > myQueue;
+            Bar bar;
+            myQueue.push_with( [&bar]( Foo& dest ) { dest = bar; } );
+            \endcode
+        */
+        template <typename Func>
+        bool push_with( Func f )
+        {
+            scoped_ptr pVal( cxx_allocator().New());
+            f( *pVal );
+            if ( base_class::push( *pVal )) {
+                pVal.release();
+                return true;
+            }
+            return false;
+        }
+
+        /// Inserts a item into priority queue
+        /**
+            If the priority queue is full, the function returns \p false,
+            no item has been added.
+            Otherwise, the function inserts a new item created from \p args arguments
+            into the heap and returns \p true.
+        */
+        template <typename... Args>
+        bool emplace( Args&&... args )
+        {
+            scoped_ptr pVal( cxx_allocator().MoveNew( std::forward<Args>(args)... ));
+            if ( base_class::push( *(pVal.get()))) {
+                pVal.release();
+                return true;
+            }
+            return false;
+        }
+
+        /// Extracts item with high priority
+        /**
+            If the priority queue is empty, the function returns \p false.
+            Otherwise, it returns \p true and \p dest contains the copy of extracted item.
+            The item is deleted from the heap.
+
+            The function uses \ref move_policy to move extracted value from the heap's top
+            to \p dest.
+
+            The function is equivalent of such call:
+            \code
+                pop_with( dest, [&dest]( value_type& src ) { move_policy()(dest, src); } );
+            \endcode
+        */
+        bool pop( value_type& dest )
+        {
+            return pop_with( [&dest]( value_type& src ) { move_policy()(dest, std::move(src)); });
+        }
+
+        /// Extracts an item with high priority
+        /**
+            If the priority queue is empty, the function returns \p false.
+            Otherwise, it returns \p true and \p dest contains the copy of extracted item.
+            The item is deleted from the heap.
+
+            \p Func is a functor called to copy popped value.
+            The functor takes one argument - a reference to removed node:
+            \code
+            cds:container::MSPriorityQueue< Foo > myQueue;
+            Bar bar;
+            myQueue.pop_with( [&bar]( Foo& src ) { bar = std::move( src );});
+            \endcode
+        */
+        template <typename Func>
+        bool pop_with( Func f )
+        {
+            value_type * pVal = base_class::pop();
+            if ( pVal ) {
+                f( *pVal );
+                cxx_allocator().Delete( pVal );
+                return true;
+            }
+            return false;
+        }
+
+        /// Clears the queue (not atomic)
+        /**
+            This function is not atomic, but thread-safe
+        */
+        void clear()
+        {
+            base_class::clear_with( []( value_type& src ) { value_deleter()(&src); } );
+        }
+
+        /// Clears the queue (not atomic)
+        /**
+            This function is not atomic, but thread-safe.
+
+            For each item removed the functor \p f is called.
+            \p Func interface is:
+            \code
+                struct clear_functor
+                {
+                    void operator()( value_type& item );
+                };
+            \endcode
+        */
+        template <typename Func>
+        void clear_with( Func f )
+        {
+            base_class::clear_with( [&f]( value_type& val ) { f(val); value_deleter()( &val ); } );
+        }
+
+        /// Checks is the priority queue is empty
+        bool empty() const
+        {
+            return base_class::empty();
+        }
+
+        /// Checks if the priority queue is full
+        bool full() const
+        {
+            return base_class::full();
+        }
+
+        /// Returns current size of priority queue
+        size_t size() const
+        {
+            return base_class::size();
+        }
+
+        /// Return capacity of the priority queue
+        size_t capacity() const
+        {
+            return base_class::capacity();
+        }
+
+        /// Returns const reference to internal statistics
+        stat const& statistics() const
+        {
+            return base_class::statistics();
+        }
+    };
+
+}} // namespace cds::container
+
+#endif // #ifndef CDSLIB_CONTAINER_MSPRIORITY_QUEUE_H