using cds::intrusive::mspriority_queue::empty_stat;
#endif
- /// Type traits for MSPriorityQueue
+ /// MSPriorityQueue traits
/**
- The type traits for cds::container::MSPriorityQueue is the same as for
- cds::intrusive::MSPriorityQueue (see cds::intrusive::mspriority_queue::type_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 type_traits: public cds::intrusive::mspriority_queue::type_traits
+ 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 MSPriorityQueue::pop functions
+ The move policy used in \p MSPriorityQueue::pop functions
to move item's value.
- Default is opt::v::assignment_move_policy.
+ Default is \p opt::v::assignment_move_policy.
*/
typedef cds::opt::v::assignment_move_policy move_policy;
};
/// Metafunction converting option list to traits
/**
- This is a wrapper for <tt> cds::opt::make_options< type_traits, Options...> </tt>
-
- See \ref MSPriorityQueue, \ref type_traits, \ref cds::opt::make_options.
+ \p Options are:
+ - \p opt::buffer - the buffer type for heap array. Possible type are: \p opt::v::static_buffer, \p opt::v::dynamic_buffer.
+ Default is \p %opt::v::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::lock::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 {
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
Template parameters:
- \p T - type to be stored in the list. The priority is a part of \p T type.
- - \p Traits - type traits. See mspriority_queue::type_traits for explanation.
-
- It is possible to declare option-based queue with cds::container::mspriority_queue::make_traits
- metafunction instead of \p Traits template argument.
- Template argument list \p Options of \p %cds::container::mspriority_queue::make_traits metafunction are:
- - opt::buffer - the buffer type for heap array. Possible type are: opt::v::static_buffer, opt::v::dynamic_buffer.
- Default is \p %opt::v::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.
- - opt::compare - priority compare functor. No default functor is provided.
- If the option is not specified, the opt::less is used.
- - opt::less - specifies binary predicate used for priority compare. Default is \p std::less<T>.
- - opt::lock_type - lock type. Default is cds::lock::Spin.
- - opt::back_off - back-off strategy. Default is cds::backoff::yield
- - opt::allocator - allocator (like \p std::allocator) for the values of queue's items.
- Default is \ref CDS_DEFAULT_ALLOCATOR
- - opt::move_policy - policy for moving item's value. Default is 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.
- - opt::stat - internal statistics. Available types: mspriority_queue::stat, mspriority_queue::empty_stat (the default)
+ - \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>
+ template <typename T, class Traits = mspriority_queue::traits >
class MSPriorityQueue: protected cds::intrusive::MSPriorityQueue< T, Traits >
{
//@cond
clear();
}
- /// Inserts a item into priority queue
+ /// Inserts an item into priority queue
/**
If the priority queue is full, the function returns \p false,
no item has been added.
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,
The function is equivalent of such call:
\code
- pop_with( dest, move_policy() );
+ pop_with( dest, [&dest]( value_type& src ) { move_policy()(dest, src); } );
\endcode
*/
bool pop( value_type& dest )
{
- return pop_with( dest, move_policy() );
+ return pop_with( [&dest]( value_type& src ) { move_policy()(dest, src); } );
}
- /// Extracts item with high priority
+ /// 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.
- The function uses \p MoveFunc \p f to move extracted value from the heap's top
- to \p dest. The interface of \p MoveFunc is:
+ \p Func is a functor called to copy popped value.
+ The functor takes one argument - a reference to removed node:
\code
- struct move_functor {
- void operator()( Q& dest, T& src );
- };
+ cds:container::MSPriorityQueue< Foo > myQueue;
+ Bar bar;
+ myQueue.pop_with( [&bar]( Foo& src ) { bar = std::move( src );});
\endcode
- In \p MoveFunc you may use move semantics for \p src argument
- since \p src will be destroyed.
*/
- template <typename Q, typename MoveFunc>
- bool pop_with( Q& dest, MoveFunc f )
+ template <typename Func>
+ bool pop_with( Func f )
{
value_type * pVal = base_class::pop();
if ( pVal ) {
- f( dest, *pVal );
+ f( *pVal );
cxx_allocator().Delete( pVal );
return true;
}
/// Clears the queue (not atomic)
/**
- This function is no atomic, but thread-safe
+ This function is not atomic, but thread-safe
*/
void clear()
{
- base_class::clear_with( []( value_type& src ) { cxx_allocator().Delete( &src ); });
+ base_class::clear_with( []( value_type& src ) { value_deleter()(&src); } );
}
/// Clears the queue (not atomic)
/**
- This function is no atomic, but thread-safe.
+ This function is not atomic, but thread-safe.
For each item removed the functor \p f is called.
\p Func interface is:
void operator()( value_type& item );
};
\endcode
- A lambda function or a function pointer can be used as \p f.
*/
template <typename Func>
void clear_with( Func f )
}
/// Synonym for \p dequeue_with() function
- template <typename Q, typename Func>
+ template <typename Func>
bool pop_with( Func f )
{
return dequeue_with( f );
/// Returns current size of priority queue
size_t size() const
{
- std::unique_lock l( m_Lock );
+ std::unique_lock<lock_type> l( m_Lock );
size_t nSize = (size_t) m_ItemCounter.value();
return nSize;
}
- switch to C++11 standard
- Removed: MichaelDeque, reason: the implementation is heavy-weighted, inefficient,
and, seems, unstable.
- - Added: cds::container::TreiberStack::pop_with(Func)
- - Added: member functions enqueue_with(Func), dequeue_with(Func) to
+ - Added: new member function pop_with(Func) to cds::container::TreiberStack
+ - Added: new member functions enqueue_with(Func), dequeue_with(Func) to
cds::container::MSQueue
cds::container::MoirQueue
cds::container::BasketQueue
cds::container::OptimisticQueue
cds::container::RWQueue
cds::container::SegmentedQueue
+ - Added: new member functions push_with(Func) and pop_with(Func) to cds::container::MSPriorityQueue
1.6.0 23.09.2014
General release
CDS_TESTHDR_SOURCES := \
$(CDS_TESTHDR_QUEUE) \
+ $(CDS_TESTHDR_PQUEUE) \
$(CDS_TESTHDR_STACK) \
$(CDS_TESTHDR_MAP) \
$(CDS_TESTHDR_DEQUE) \
$(CDS_TESTHDR_ORDLIST) \
- $(CDS_TESTHDR_PQUEUE) \
$(CDS_TESTHDR_SET) \
$(CDS_TESTHDR_TREE) \
$(CDS_TESTHDR_MISC)
void fcDeque_mutex()
{
- struct deque_traits : public cds::container::fcdeque::traits
+ struct deque_traits : public
+ cds::container::fcdeque::make_traits<
+ cds::opt::enable_elimination< true >
+ >::type
{
- static CDS_CONSTEXPR const bool enable_elimination = true;
typedef std::mutex lock_type;
};
typedef cds::container::FCDeque<int, std::deque<int>, deque_traits > deque_type;
#include "priority_queue/hdr_intrusive_pqueue.h"
#include <cds/intrusive/mspriority_queue.h>
-#include <mutex>
namespace priority_queue {
namespace intrusive_pqueue {
void IntrusivePQueueHdrTest::MSPQueue_dyn()
{
- typedef cds::intrusive::MSPriorityQueue< IntrusivePQueueHdrTest::key_type,
- cds::intrusive::mspriority_queue::make_traits<
- cds::opt::buffer< buffer_type >
- >::type
- > pqueue;
+ struct pqueue_traits : public cds::intrusive::mspriority_queue::traits
+ {
+ typedef buffer_type buffer;
+ };
+ typedef cds::intrusive::MSPriorityQueue< IntrusivePQueueHdrTest::key_type, pqueue_traits > pqueue;
test_msq_dyn<pqueue>();
}
void IntrusivePQueueHdrTest::MSPQueue_dyn_cmp()
{
- typedef cds::intrusive::MSPriorityQueue< IntrusivePQueueHdrTest::key_type,
- cds::intrusive::mspriority_queue::make_traits<
- cds::opt::buffer< buffer_type >
- ,cds::opt::compare< IntrusivePQueueHdrTest::compare >
- >::type
- > pqueue;
+ struct pqueue_traits : public cds::intrusive::mspriority_queue::traits
+ {
+ typedef buffer_type buffer;
+ typedef IntrusivePQueueHdrTest::compare compare;
+ };
+ typedef cds::intrusive::MSPriorityQueue< IntrusivePQueueHdrTest::key_type, pqueue_traits > pqueue;
test_msq_dyn<pqueue>();
}
void IntrusivePQueueHdrTest::MSPQueue_dyn_less()
{
- typedef cds::intrusive::MSPriorityQueue< IntrusivePQueueHdrTest::key_type,
- cds::intrusive::mspriority_queue::make_traits<
+ struct pqueue_traits : public
+ cds::intrusive::mspriority_queue::make_traits <
cds::opt::buffer< buffer_type >
- ,cds::opt::less< std::less<IntrusivePQueueHdrTest::key_type> >
- >::type
- > pqueue;
+ , cds::opt::less < std::less<IntrusivePQueueHdrTest::key_type> >
+ > ::type
+ {};
+ typedef cds::intrusive::MSPriorityQueue< IntrusivePQueueHdrTest::key_type, pqueue_traits > pqueue;
test_msq_dyn<pqueue>();
}
#include "priority_queue/hdr_intrusive_pqueue.h"
#include <cds/intrusive/mspriority_queue.h>
-#include <mutex>
namespace priority_queue {
namespace intrusive_pqueue {
void IntrusivePQueueHdrTest::MSPQueue_st_cmp_mtx()
{
- typedef cds::intrusive::MSPriorityQueue< IntrusivePQueueHdrTest::key_type,
- cds::intrusive::mspriority_queue::make_traits<
- cds::opt::buffer< buffer_type >
- ,cds::opt::compare< IntrusivePQueueHdrTest::compare >
- ,cds::opt::lock_type<std::mutex>
- >::type
- > pqueue;
+ struct pqueue_traits : public cds::intrusive::mspriority_queue::traits
+ {
+ typedef buffer_type buffer;
+ typedef IntrusivePQueueHdrTest::compare compare;
+ typedef std::mutex lock_type;
+ };
+ typedef cds::intrusive::MSPriorityQueue< IntrusivePQueueHdrTest::key_type, pqueue_traits > pqueue;
test_msq_stat<pqueue>();
}
#include "priority_queue/hdr_pqueue.h"
#include <cds/container/mspriority_queue.h>
-#include <mutex>
namespace priority_queue {
namespace pqueue {
void PQueueHdrTest::MSPQueue_dyn_cmpless()
{
- typedef cds::container::MSPriorityQueue< PQueueHdrTest::value_type,
- cds::container::mspriority_queue::make_traits<
- cds::opt::buffer< buffer_type >
- ,cds::opt::less< PQueueHdrTest::less >
- ,cds::opt::compare< PQueueHdrTest::compare >
- >::type
- > pqueue;
+ struct pqueue_traits : public cds::container::mspriority_queue::traits
+ {
+ typedef buffer_type buffer;
+ typedef PQueueHdrTest::less less;
+ typedef PQueueHdrTest::compare compare;
+ };
+ typedef cds::container::MSPriorityQueue< PQueueHdrTest::value_type, pqueue_traits > pqueue;
test_msq_dyn<pqueue>();
}
#include "priority_queue/hdr_pqueue.h"
#include <cds/container/mspriority_queue.h>
-#include <mutex>
namespace priority_queue {
namespace pqueue {
}
};
- struct move_functor
- {
- void operator()( int& dest, value_type const& src ) const
- {
- dest = src.k;
- }
- };
-
protected:
template <class PQueue>
void test_bounded_with( PQueue& pq )
// Push test
for ( value_type * p = pFirst; p < pLast; ++p ) {
switch ( pq.size() & 3 ) {
+ case 0:
+ CPPUNIT_ASSERT( pq.push_with( [p]( value_type& dest ) { dest = *p; } ));
+ break;
case 1:
CPPUNIT_ASSERT( pq.emplace( p->k, p->v ));
break;
nPrev = kv.k;
}
else {
- CPPUNIT_ASSERT( pq.pop_with( key, move_functor() ));
+ CPPUNIT_ASSERT( pq.pop_with( [&key]( value_type& src ) { key = src.k; } ) );
CPPUNIT_CHECK_EX( key == nPrev - 1, "Expected=" << nPrev - 1 << ", current=" << key );
nPrev = key;
}
other_item v;
nCount = 0;
+ size_t nFuncCount = 0;
while ( !q.empty() ) {
if ( nCount & 1 ) {
- CPPUNIT_ASSERT( q.pop_with( [&v, &nCount]( item& src ) {v.nVal = src.nVal; ++nCount; } ));
+ CPPUNIT_ASSERT( q.pop_with( [&v, &nFuncCount]( item& src ) {v.nVal = src.nVal; ++nFuncCount; } ));
}
else {
- CPPUNIT_ASSERT( q.dequeue_with( [&v, &nCount]( item& src ) {v.nVal = src.nVal; ++nCount; } ));
+ CPPUNIT_ASSERT( q.dequeue_with( [&v, &nFuncCount]( item& src ) {v.nVal = src.nVal; ++nFuncCount; } ));
}
// It is possible c_nItemCount % quasi_factor() != 0
CPPUNIT_CHECK_EX( nMin <= v.nVal && v.nVal <= nMax, nMin << " <= " << v.nVal << " <= " << nMax );
++nCount;
- CPPUNIT_CHECK( pf.nCount == nCount );
+ CPPUNIT_CHECK( nFuncCount == nCount );
CPPUNIT_CHECK( misc::check_size( q, c_nItemCount - nCount ));
}
CPPUNIT_CHECK( nCount == c_nItemCount );
void TestFCStack::FCStack_deque_elimination()
{
- struct stack_traits : public cds::container::fcstack::traits
- {
- static CDS_CONSTEXPR const bool enable_elimination = true;
- };
+ struct stack_traits : public
+ cds::container::fcstack::make_traits <
+ cds::opt::enable_elimination < true >
+ > ::type
+ {};
typedef cds::container::FCStack< unsigned int, std::stack<unsigned int, std::deque<unsigned int> >, stack_traits > stack_type;
test<stack_type>();
}
#include <deque>
#include <boost/container/stable_vector.hpp>
#include <boost/container/deque.hpp>
-#include <mutex>
#include <cds/lock/spinlock.h>
#include "print_ellenbintree_stat.h"
};
-
// MSPriorityQueue
- typedef cc::MSPriorityQueue< Value,
- typename cc::mspriority_queue::make_traits<
- co::buffer< co::v::static_buffer< char, c_nBoundedCapacity > >
- >::type
- > MSPriorityQueue_static_less;
+ struct traits_MSPriorityQueue_static_less : public
+ cc::mspriority_queue::make_traits <
+ co::buffer < co::v::static_buffer< char, c_nBoundedCapacity > >
+ > ::type
+ {};
+ typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_less > MSPriorityQueue_static_less;
- typedef cc::MSPriorityQueue< Value,
- typename cc::mspriority_queue::make_traits<
- co::buffer< co::v::static_buffer< char, c_nBoundedCapacity > >
- ,co::stat< cc::mspriority_queue::stat<> >
- >::type
- > MSPriorityQueue_static_less_stat;
+ struct traits_MSPriorityQueue_static_less_stat : public cc::mspriority_queue::traits
+ {
+ typedef co::v::static_buffer< char, c_nBoundedCapacity > buffer;
+ typedef cc::mspriority_queue::stat<> stat;
+ };
+ typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_less_stat > MSPriorityQueue_static_less_stat;
- typedef cc::MSPriorityQueue< Value,
- typename cc::mspriority_queue::make_traits<
+ struct traits_MSPriorityQueue_static_cmp : public
+ cc::mspriority_queue::make_traits <
co::buffer< co::v::static_buffer< char, c_nBoundedCapacity > >
- ,co::compare< cmp >
- >::type
- > MSPriorityQueue_static_cmp;
+ , co::compare < cmp >
+ > ::type
+ {};
+ typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_cmp > MSPriorityQueue_static_cmp;
- typedef cc::MSPriorityQueue< Value,
- typename cc::mspriority_queue::make_traits<
+ struct traits_MSPriorityQueue_static_mutex : public
+ cc::mspriority_queue::make_traits<
co::buffer< co::v::static_buffer< char, c_nBoundedCapacity > >
- ,co::lock_type<std::mutex>
+ , co::lock_type<std::mutex>
>::type
- > MSPriorityQueue_static_mutex;
+ {};
+ typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_static_mutex > MSPriorityQueue_static_mutex;
- typedef cc::MSPriorityQueue< Value,
- typename cc::mspriority_queue::make_traits<
+ struct traits_MSPriorityQueue_dyn_less : public
+ cc::mspriority_queue::make_traits<
co::buffer< co::v::dynamic_buffer< char > >
>::type
- > MSPriorityQueue_dyn_less;
+ {};
+ typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_less > MSPriorityQueue_dyn_less;
- typedef cc::MSPriorityQueue< Value,
- typename cc::mspriority_queue::make_traits<
+ struct traits_MSPriorityQueue_dyn_less_stat : public
+ cc::mspriority_queue::make_traits <
co::buffer< co::v::dynamic_buffer< char > >
- ,co::stat< cc::mspriority_queue::stat<> >
- >::type
- > MSPriorityQueue_dyn_less_stat;
+ , co::stat < cc::mspriority_queue::stat<> >
+ > ::type
+ {};
+ typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_less_stat > MSPriorityQueue_dyn_less_stat;
- typedef cc::MSPriorityQueue< Value,
- typename cc::mspriority_queue::make_traits<
+ struct traits_MSPriorityQueue_dyn_cmp : public
+ cc::mspriority_queue::make_traits <
co::buffer< co::v::dynamic_buffer< char > >
- ,co::compare< cmp >
- >::type
- > MSPriorityQueue_dyn_cmp;
+ , co::compare < cmp >
+ > ::type
+ {};
+ typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_cmp > MSPriorityQueue_dyn_cmp;
- typedef cc::MSPriorityQueue< Value,
- typename cc::mspriority_queue::make_traits<
+ struct traits_MSPriorityQueue_dyn_mutex : public
+ cc::mspriority_queue::make_traits <
co::buffer< co::v::dynamic_buffer< char > >
- ,co::lock_type<std::mutex>
- >::type
- > MSPriorityQueue_dyn_mutex;
+ , co::lock_type < std::mutex >
+ > ::type
+ {};
+ typedef cc::MSPriorityQueue< Value, traits_MSPriorityQueue_dyn_mutex > MSPriorityQueue_dyn_mutex;
// Priority queue based on EllenBinTreeSet
namespace details {
- template <typename T, typename Traits=cds::container::fcdeque::type_traits>
+ template <typename T, typename Traits=cds::container::fcdeque::traits>
class FCDequeL: public cds::container::FCDeque<T, std::deque<T>, Traits >
{
typedef cds::container::FCDeque<T, std::deque<T>, Traits > base_class;
}
};
- template <typename T, typename Traits=cds::container::fcdeque::type_traits>
+ template <typename T, typename Traits=cds::container::fcdeque::traits>
class FCDequeR: public cds::container::FCDeque<T, std::deque<T>, Traits >
{
typedef cds::container::FCDeque<T, std::deque<T>, Traits > base_class;