📄 concurrent_queue.h
字号:
_Destroyer _D(_From);
*static_cast<_Ty*>(_Dst) = _From;
}
/*overide*/ virtual _Page *_Allocate_page()
{
size_t _N = sizeof(_Page) + _Items_per_page*_Item_size;
_Page *_Pg = reinterpret_cast<_Page*>(_My_allocator.allocate( _N ));
if( !_Pg )
_Internal_throw_exception();
return _Pg;
}
/*override*/ virtual void _Deallocate_page( _Page *_Pg )
{
size_t _N = sizeof(_Page) + _Items_per_page*_Item_size;
_My_allocator.deallocate( reinterpret_cast<char*>(_Pg), _N );
}
public:
/// <summary>
/// A type that represents the data type stored in a concurrent queue.
/// </summary>
/**/
typedef _Ty value_type;
/// <summary>
/// A type that represents the allocator class for the concurrent queue.
/// </summary>
/**/
typedef _Ax allocator_type;
/// <summary>
/// A type that provides a reference to an element stored in a concurrent queue.
/// </summary>
/**/
typedef _Ty& reference;
/// <summary>
/// A type that provides a reference to a <c>const</c> element stored in a concurrent queue for reading and
/// performing <c>const</c> operations.
/// </summary>
/**/
typedef const _Ty& const_reference;
/// <summary>
/// A type that counts the number of elements in a concurrent queue.
/// </summary>
/**/
typedef std::size_t size_type;
/// <summary>
/// A type that provides the signed distance between two elements in a concurrent queue.
/// </summary>
/**/
typedef std::ptrdiff_t difference_type;
/// <summary>
/// Constructs a concurrent queue.
/// </summary>
/// <param name="_Al">
/// The allocator class to use with this object.
/// </param>
/// <remarks>
/// All constructors store an allocator object <paramref name="_Al"/> and initialize the queue.
/// <para>The first constructor specifies an empty initial queue and explicitly specifies the allocator
/// type to be used.</para>
/// <para>The second constructor specifies a copy of the concurrent queue <paramref name="_OtherQ"/>.</para>
/// <para>The third constructor specifies values supplied by the iterator range
/// [<paramref name="_Begin"/>, <paramref name="_End"/>).</para>
/// </remarks>
/**/
explicit concurrent_queue(const allocator_type &_Al = allocator_type())
: _Concurrent_queue_base_v4( sizeof(_Ty) ), _My_allocator( _Al )
{
}
/// <summary>
/// Constructs a concurrent queue.
/// </summary>
/// <param name="_OtherQ">
/// The source <c>concurrent_queue</c> object to copy elements from.
/// </param>
/// <param name="_Al">
/// The allocator class to use with this object.
/// </param>
/// <remarks>
/// All constructors store an allocator object <paramref name="_Al"/> and initialize the queue.
/// <para>The first constructor specifies an empty initial queue and explicitly specifies the allocator
/// type to be used.</para>
/// <para>The second constructor specifies a copy of the concurrent queue <paramref name="_OtherQ"/>.</para>
/// <para>The third constructor specifies values supplied by the iterator range
/// [<paramref name="_Begin"/>, <paramref name="_End"/>).</para>
/// </remarks>
/**/
concurrent_queue(const concurrent_queue& _OtherQ, const allocator_type &_Al = allocator_type());
/// <summary>
/// Constructs a concurrent queue.
/// </summary>
/// <typeparam name="_InputIterator">
/// The type of the input iterator that specifies a range of values.
/// </typeparam>
/// <param name="_Begin">
/// Position of the first element in the range of elements to be copied.
/// </param>
/// <param name="_End">
/// Position of the first element beyond the range of elements to be copied.
/// </param>
/// <remarks>
/// All constructors store an allocator object <paramref name="_Al"/> and initialize the queue.
/// <para>The first constructor specifies an empty initial queue and explicitly specifies the allocator
/// type to be used.</para>
/// <para>The second constructor specifies a copy of the concurrent queue <paramref name="_OtherQ"/>.</para>
/// <para>The third constructor specifies values supplied by the iterator range
/// [<paramref name="_Begin"/>, <paramref name="_End"/>).</para>
/// </remarks>
/**/
template<typename _InputIterator>
concurrent_queue(_InputIterator _Begin, _InputIterator _End)
: _Concurrent_queue_base_v4( sizeof(_Ty) ), _My_allocator( allocator_type() )
{
while (_Begin != _End)
{
this->push(*_Begin);
++_Begin;
}
}
/// <summary>
/// Destroys the concurrent queue.
/// </summary>
/**/
~concurrent_queue();
/// <summary>
/// Enqueues an item at tail end of the concurrent queue. This method is concurrency-safe.
/// </summary>
/// <param name="_Src">
/// The item to be added to the queue.
/// </param>
/// <remarks>
/// <c>push</c> is concurrency-safe with respect to calls to the methods <c>push</c>, <c>try_pop</c>, and <c>empty</c>.
/// </remarks>
/**/
void push( const _Ty& _Src )
{
_Internal_push( &_Src );
}
/// <summary>
/// Dequeues an item from the queue if one is available. This method is concurrency-safe.
/// </summary>
/// <param name="_Dest">
/// A reference to a location to store the dequeued item.
/// </param>
/// <returns>
/// <c>true</c> if an item was successfully dequeued,<c>false</c> otherwise.
/// </returns>
/// <remarks>
/// If an item was successfully dequeued, the parameter <paramref name="_Dest"/> receives the
/// dequeued value, the original value held in the queue is destroyed, and this function returns
/// <c>true</c>. If there was no item to dequeue, this function returns <c>false</c> without blocking,
/// and the contents of the <paramref name="_Dest"/> parameter are undefined.
/// <para><c>try_pop</c> is concurrency-safe with respect to calls to the methods <c>push</c>, <c>try_pop</c>,
/// and <c>empty</c>.</para>
/// </remarks>
/**/
bool try_pop( _Ty& _Dest )
{
return _Internal_pop_if_present( &_Dest );
}
/// <summary>
/// Returns the number of items in the queue. This method is not concurrency-safe.
/// </summary>
/// <returns>
/// The size of the concurrent queue.
/// </returns>
/// <remarks>
/// <c>unsafe_size</c> is not concurrency-safe and can produce incorrect results if called concurrently
/// with calls to the methods <c>push</c>, <c>try_pop</c>, and <c>empty</c>.
/// </remarks>
/**/
size_type unsafe_size() const
{
return _Internal_size();
}
/// <summary>
/// Tests if the concurrent queue is empty at the moment this method is called. This method is concurrency-safe.
/// </summary>
/// <returns>
/// <c>true</c> if the concurrent queue was empty at the moment we looked, <c>false</c> otherwise.
/// </returns>
/// <remarks>
/// While this method is concurrency-safe with respect to calls to the methods <c>push</c>, <c>try_pop</c>, and
/// <c>empty</c>, the value returned might be incorrect by the time it is inspected by the calling thread.
/// </remarks>
/**/
bool empty() const
{
return _Internal_empty();
}
/// <summary>
/// Returns a copy of the allocator used to construct the concurrent queue. This method is concurrency-safe.
/// </summary>
/// <returns>
/// A copy of the allocator used to construct the concurrent queue.
/// </returns>
/**/
allocator_type get_allocator() const
{
return this->_My_allocator;
}
/// <summary>
/// Clears the concurrent queue, destroying any currently enqueued elements. This method is not concurrency-safe.
/// </summary>
/**/
void clear();
/// <summary>
/// A type that represents a non-thread-safe iterator over the elements in a concurrent queue.
/// </summary>
/**/
typedef details::_Concurrent_queue_iterator<concurrent_queue,_Ty> iterator;
/// <summary>
/// A type that represents a non-thread-safe <c>const</c> iterator over elements in a concurrent queue.
/// </summary>
/**/
typedef details::_Concurrent_queue_iterator<concurrent_queue,const _Ty> const_iterator;
/// <summary>
/// Returns an iterator of type <typeparamref name="iterator"/> or <typeparamref name="const_iterator"/> to the
/// beginning of the concurrent queue. This method is not concurrency-safe.
/// </summary>
/// <returns>
/// An iterator of type <typeparamref name="iterator"/> or <typeparamref name="const_iterator"/> to the
/// beginning of the concurrent queue object.
/// </returns>
/// <remarks>
/// The iterators for the <c>concurrent_queue</c> class are primarily intended for debugging, as they are slow, and iteration
/// is not concurrency-safe with respect to other queue operations.
/// </remarks>
/**/
iterator unsafe_begin()
{
return iterator(*this);
}
/// <summary>
/// Returns an iterator of type <typeparamref name="iterator"/> or <typeparamref name="const_iterator"/> to the
/// end of the concurrent queue. This method is not concurrency-safe.
/// </summary>
/// <returns>
/// An iterator of type <typeparamref name="iterator"/> or <typeparamref name="const_iterator"/> to the
/// end of the concurrent queue.
/// </returns>
/// <remarks>
/// The iterators for the <c>concurrent_queue</c> class are primarily intended for debugging, as they are slow, and iteration
/// is not concurrency-safe with respect to other queue operations.
/// </remarks>
/**/
iterator unsafe_end()
{
return iterator();
}
/// <summary>
/// Returns an iterator of type <typeparamref name="iterator"/> or <typeparamref name="const_iterator"/> to the
/// beginning of the concurrent queue. This method is not concurrency-safe.
/// </summary>
/// <returns>
/// An iterator of type <typeparamref name="iterator"/> or <typeparamref name="const_iterator"/> to the
/// beginning of the concurrent queue.
/// </returns>
/// <remarks>
/// The iterators for the <c>concurrent_queue</c> class are primarily intended for debugging, as they are slow, and iteration
/// is not concurrency-safe with respect to other queue operations.
/// </remarks>
/**/
const_iterator unsafe_begin() const
{
return const_iterator(*this);
}
/// <summary>
/// Returns an iterator of type <typeparamref name="iterator"/> or <typeparamref name="const_iterator"/> to the
/// end of the concurrent queue. This method is not concurrency-safe.
/// </summary>
/// <returns>
/// An iterator of type <typeparamref name="iterator"/> or <typeparamref name="const_iterator"/> to the
/// end of the concurrent queue.
/// </returns>
/// <remarks>
/// The iterators for the <c>concurrent_queue</c> class are primarily intended for debugging, as they are slow, and iteration
/// is not concurrency-safe with respect to other queue operations.
/// </remarks>
/**/
const_iterator unsafe_end() const
{
return const_iterator();
}
};
/// <summary>
/// Constructs a concurrent queue.
/// </summary>
/// <param name="_OtherQ">
/// The source <c>concurrent_queue</c> object to copy elements from.
/// </param>
/// <param name="_Al">
/// The allocator class to use with this object.
/// </param>
/// <remarks>
/// All constructors store an allocator object <paramref name="_Al"/> and initialize the queue.
/// <para>The first constructor specifies an empty initial queue and explicitly specifies the allocator
/// type to be used</para>
/// <para>The second constructor specifies a copy of the concurrent queue <paramref name="_OtherQ"/>.</para>
/// <para>The third constructor specifies values supplied by the iterator range
/// [<paramref name="_Begin"/>, <paramref name="_End"/>).</para>
/// </remarks>
/**/
template<typename _Ty, class _Ax>
concurrent_queue<_Ty,_Ax>::concurrent_queue(const concurrent_queue& _Queue, const allocator_type& _Al = allocator_type())
: _Concurrent_queue_base_v4( sizeof(_Ty) ), _My_allocator(_Al)
{
concurrent_queue::const_iterator _QEnd = _Queue.unsafe_end();
for (concurrent_queue::const_iterator _It = _Queue.unsafe_begin(); _It != _QEnd; ++_It)
this->push(*_It);
}
/// <summary>
/// Destroys the concurrent queue.
/// </summary>
/**/
template<typename _Ty, class _Ax>
concurrent_queue<_Ty,_Ax>::~concurrent_queue()
{
clear();
_Internal_finish_clear();
}
/// <summary>
/// Clears the concurrent queue, destroying any currently enqueued elements. This method is not concurrency-safe.
/// </summary>
/**/
template<typename _Ty, class _Ax>
void concurrent_queue<_Ty,_Ax>::clear()
{
while( !empty() )
{
char _Buf[sizeof(_Ty)];
if (!_Internal_pop_if_present(reinterpret_cast<_Ty*>(_Buf)))
{
_ASSERTE(empty());
break;
}
}
}
} // namespace Concurrency
#pragma pack(pop)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -