/// Dequeues a value from the queue
/**
If queue is not empty, the function returns \p true, \p dest contains copy of
- dequeued value. The assignment operator for type \ref value_type is invoked.
+ dequeued value. The assignment operator for \p value_type is invoked.
If queue is empty, the function returns \p false, \p dest is unchanged.
*/
bool dequeue( value_type& dest )
{
- return dequeue_with( [&dest]( value_type& src ) { dest = src; } );
+ return dequeue_with( [&dest]( value_type& src ) { dest = std::move( src );});
}
/// Dequeues a value using a functor
assert( pRec->pValPop );
pRec->bEmpty = m_Deque.empty();
if ( !pRec->bEmpty ) {
- *(pRec->pValPop) = m_Deque.front();
+ *(pRec->pValPop) = std::move( m_Deque.front());
m_Deque.pop_front();
}
break;
assert( pRec->pValPop );
pRec->bEmpty = m_Deque.empty();
if ( !pRec->bEmpty ) {
- *(pRec->pValPop) = m_Deque.back();
+ *(pRec->pValPop) = std::move( m_Deque.back());
m_Deque.pop_back();
}
break;
for ( fc_iterator it = itBegin, itPrev = itEnd; it != itEnd; ++it ) {
switch ( it->op() ) {
case op_push_front:
+ if ( itPrev != itEnd
+ && (itPrev->op() == op_pop_front || (m_Deque.empty() && itPrev->op() == op_pop_back)) )
+ {
+ collide( *it, *itPrev );
+ itPrev = itEnd;
+ }
+ else
+ itPrev = it;
+ break;
case op_push_front_move:
if ( itPrev != itEnd
&& (itPrev->op() == op_pop_front || ( m_Deque.empty() && itPrev->op() == op_pop_back )))
{
- collide( *it, *itPrev );
+ collide_move( *it, *itPrev );
itPrev = itEnd;
}
else
itPrev = it;
break;
case op_push_back:
- case op_push_back_move:
if ( itPrev != itEnd
- && (itPrev->op() == op_pop_back || ( m_Deque.empty() && itPrev->op() == op_pop_front )))
+ && (itPrev->op() == op_pop_back || (m_Deque.empty() && itPrev->op() == op_pop_front)) )
{
collide( *it, *itPrev );
itPrev = itEnd;
else
itPrev = it;
break;
- case op_pop_front:
+ case op_push_back_move:
if ( itPrev != itEnd
- && ( itPrev->op() == op_push_front || itPrev->op() == op_push_front_move
- || ( m_Deque.empty() && ( itPrev->op() == op_push_back || itPrev->op() == op_push_back_move ))))
+ && (itPrev->op() == op_pop_back || ( m_Deque.empty() && itPrev->op() == op_pop_front )))
{
- collide( *itPrev, *it );
+ collide_move( *it, *itPrev );
itPrev = itEnd;
}
else
itPrev = it;
break;
+ case op_pop_front:
+ if ( itPrev != itEnd ) {
+ if ( m_Deque.empty() ) {
+ switch ( itPrev->op() ) {
+ case op_push_back:
+ collide( *itPrev, *it );
+ itPrev = itEnd;
+ break;
+ case op_push_back_move:
+ collide_move( *itPrev, *it );
+ itPrev = itEnd;
+ break;
+ default:
+ itPrev = it;
+ break;
+ }
+ }
+ else {
+ switch ( itPrev->op() ) {
+ case op_push_front:
+ collide( *itPrev, *it );
+ itPrev = itEnd;
+ break;
+ case op_push_front_move:
+ collide_move( *itPrev, *it );
+ itPrev = itEnd;
+ break;
+ default:
+ itPrev = it;
+ break;
+ }
+ }
+ }
+ else
+ itPrev = it;
+ break;
case op_pop_back:
- if ( itPrev != itEnd
- && ( itPrev->op() == op_push_back || itPrev->op() == op_push_back_move
- || ( m_Deque.empty() && ( itPrev->op() == op_push_front || itPrev->op() == op_push_front_move ))))
- {
- collide( *itPrev, *it );
- itPrev = itEnd;
+ if ( itPrev != itEnd ) {
+ if ( m_Deque.empty() ) {
+ switch ( itPrev->op() ) {
+ case op_push_front:
+ collide( *itPrev, *it );
+ itPrev = itEnd;
+ break;
+ case op_push_front_move:
+ collide_move( *itPrev, *it );
+ itPrev = itEnd;
+ break;
+ default:
+ itPrev = it;
+ break;
+ }
+ }
+ else {
+ switch ( itPrev->op() ) {
+ case op_push_back:
+ collide( *itPrev, *it );
+ itPrev = itEnd;
+ break;
+ case op_push_back_move:
+ collide_move( *itPrev, *it );
+ itPrev = itEnd;
+ break;
+ default:
+ itPrev = it;
+ break;
+ }
+ }
}
else
itPrev = it;
m_FlatCombining.operation_done( recPop );
m_FlatCombining.internal_statistics().onCollide();
}
+
+ void collide_move( fc_record& recPush, fc_record& recPop )
+ {
+ *(recPop.pValPop) = std::move( *(recPush.pValPush));
+ recPop.bEmpty = false;
+ m_FlatCombining.operation_done( recPush );
+ m_FlatCombining.operation_done( recPop );
+ m_FlatCombining.internal_statistics().onCollide();
+ }
//@endcond
};
assert( pRec->pValPop );
pRec->bEmpty = m_PQueue.empty();
if ( !pRec->bEmpty ) {
- *(pRec->pValPop) = m_PQueue.top();
+ *(pRec->pValPop) = std::move( m_PQueue.top());
m_PQueue.pop();
}
break;
assert( pRec->pValDeq );
pRec->bEmpty = m_Queue.empty();
if ( !pRec->bEmpty ) {
- *(pRec->pValDeq) = m_Queue.front();
+ *(pRec->pValDeq) = std::move( m_Queue.front());
m_Queue.pop();
}
break;
assert( pRec->pValPop );
pRec->bEmpty = m_Stack.empty();
if ( !pRec->bEmpty ) {
- *(pRec->pValPop) = m_Stack.top();
+ *(pRec->pValPop) = std::move( m_Stack.top());
m_Stack.pop();
}
break;
*/
bool dequeue( value_type& dest )
{
- return dequeue_with( [&dest]( value_type& src ) { dest = src; } );
+ return dequeue_with( [&dest]( value_type& src ) { dest = std::move( src ); });
}
/// Dequeues a value using a functor
*/
bool pop( value_type& dest )
{
- return pop_with( [&dest]( value_type& src ) { move_policy()(dest, src); } );
+ return pop_with( [&dest]( value_type& src ) { move_policy()(dest, std::move(src)); });
}
/// Extracts an item with high priority
*/
bool dequeue( value_type& dest )
{
- return dequeue_with( [&dest]( value_type& src ) { dest = src; } );
+ return dequeue_with( [&dest]( value_type& src ) { dest = std::move( src );});
}
/// Dequeues a value using a functor
*/
bool dequeue( value_type& dest )
{
- return dequeue_with( [&dest]( value_type& src ) { dest = src; } );
+ return dequeue_with( [&dest]( value_type& src ) { dest = std::move( src ); });
}
/// Dequeues a value using a functor
*/
bool dequeue( value_type& dest )
{
- return dequeue_with( [&dest]( value_type& src ) { dest = src; } );
+ return dequeue_with( [&dest]( value_type& src ) { dest = std::move( src ); });
}
/// Dequeues a value using a functor
*/
bool dequeue( value_type& dest )
{
- return dequeue_with( [&dest]( value_type& src ) { dest = src; });
+ return dequeue_with( [&dest]( value_type& src ) { dest = std::move( src );});
}
/// Dequeues a value using a functor
*/
bool pop( value_type& val )
{
- return pop_with( [&val]( value_type& src ) { val = src; } );
+ return pop_with( [&val]( value_type& src ) { val = std::move(src); } );
}
/// Pops an item from the stack with functor
/**
+ \p Func can be used to copy/move popped item from the stack.
\p Func interface is:
\code
void func( value_type& src );
\endcond
where \p src - item popped.
-
- The \p %pop_with can be used to move item from the stack to user-provided storage:
- \code
- cds::container::TreiberStack<cds::gc::HP, std::string > myStack;
- //...
-
- std::string dest;
- myStack.pop_with( [&dest]( std::string& src ) { dest = std::move( src ); } );
- \endcode
*/
template <typename Func>
bool pop_with( Func f )
*/
bool dequeue( value_type& dest )
{
- return dequeue_with( [&dest]( value_type& src ) { dest = src; } );
+ return dequeue_with( [&dest]( value_type& src ) { dest = std::move( src );});
}
/// Synonym for \p dequeue() function
/// Dequeues a value from the queue
/**
- If queue is not empty, the function returns \p true, \p dest contains copy of
+ If queue is not empty, the function returns \p true, \p dest contains a copy of
dequeued value. The assignment operator for type \ref value_type is invoked.
If queue is empty, the function returns \p false, \p dest is unchanged.
*/
bool dequeue(value_type & dest )
{
- return dequeue_with( [&dest]( value_type& src ){ dest = src; } );
+ return dequeue_with( [&dest]( value_type& src ){ dest = std::move( src );});
}
/// Synonym for \p dequeue()
}
};
- /// \p opt::move_policy based on assignment operator
+ /// \p opt::move_policy based on move-assignment operator
struct assignment_move_policy
{
- /// <tt> dest = src </tt>
+ /// <tt> dest = std::move( src ) </tt>
template <typename T>
- void operator()( T& dest, T const& src ) const
+ void operator()( T& dest, T&& src ) const
{
- dest = src;
+ dest = std::move( src );
}
};
template <class PQueue>
void test_msq_stat()
{
- PQueue pq( 0 ); // argument should be ignored for static buffer
- test_bounded_with( pq );
+ std::unique_ptr< PQueue > pq( new PQueue(0)); // argument should be ignored for static buffer
+ test_bounded_with( *pq );
}
template <class PQueue>
void test_msq_dyn()
template <class PQueue>
void test_msq_stat()
{
- PQueue pq( 0 ); // argument should be ignored for static buffer
- test_bounded_with( pq );
+ std::unique_ptr< PQueue > pq( new PQueue( 0 )); // argument should be ignored for static buffer
+ test_bounded_with( *pq );
}
template <class PQueue>
void test_msq_dyn()