8 #include <density/default_allocator.h> 10 #include <density/raw_atomic.h> 11 #include <density/runtime_type.h> 15 #include <type_traits> 18 #if defined(_M_IX86) || defined(_M_X64) 19 #include <immintrin.h> 22 #pragma warning(disable : 4324) // structure was padded due to alignment specifier 25 #include <density/detail/lf_queue_base.h> 26 #include <density/detail/lf_queue_head_multiple.h> 27 #include <density/detail/lf_queue_head_single.h> 28 #include <density/detail/lf_queue_tail_single.h> 29 #include <density/detail/sp_queue_tail_multiple.h> 36 typename RUNTIME_TYPE,
37 typename ALLOCATOR_TYPE,
39 typename BUSY_WAIT_FUNC>
40 using SpQueue_Tail =
typename std::conditional<
42 LFQueue_Tail<RUNTIME_TYPE, ALLOCATOR_TYPE, concurrency_single, consistency_sequential>,
43 SpQueue_TailMultiple<RUNTIME_TYPE, ALLOCATOR_TYPE, BUSY_WAIT_FUNC>>::type;
53 #if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) 56 std::this_thread::yield();
209 :
private detail::LFQueue_Head<
212 CONSUMER_CARDINALITY,
213 detail::SpQueue_Tail<RUNTIME_TYPE, ALLOCATOR_TYPE, PROD_CARDINALITY, BUSY_WAIT_FUNC>>
216 using Base = detail::LFQueue_Head<
219 CONSUMER_CARDINALITY,
220 detail::SpQueue_Tail<RUNTIME_TYPE, ALLOCATOR_TYPE, PROD_CARDINALITY, BUSY_WAIT_FUNC>>;
221 using Base::try_inplace_allocate;
222 using typename Base::Allocation;
223 using typename Base::Consume;
224 using typename Base::ControlBlock;
227 enum class PrivateType
233 constexpr
static size_t min_alignment = Base::min_alignment;
235 using runtime_type = RUNTIME_TYPE;
236 using value_type = std::pair<const runtime_type &, void * const>;
237 using allocator_type = ALLOCATOR_TYPE;
238 using pointer = value_type *;
239 using const_pointer =
const value_type *;
240 using reference = value_type;
241 using const_reference =
const value_type &;
242 using size_type = std::size_t;
243 using difference_type = std::ptrdiff_t;
253 static constexpr
bool concurrent_put_consumes =
true;
256 static constexpr
bool is_seq_cst =
true;
260 ALLOCATOR_TYPE::page_alignment >= ALLOCATOR_TYPE::page_size &&
261 (ALLOCATOR_TYPE::page_alignment % min_alignment) == 0,
262 "The alignment of the pages must be a power of 2, greater or equal to the size of the " 263 "pages, and a multiple of min_alignment");
266 ALLOCATOR_TYPE::page_size > (min_alignment +
alignof(ControlBlock)) * 4,
267 "Invalid page size");
290 constexpr explicit
sp_heter_queue(const ALLOCATOR_TYPE & i_source_allocator) noexcept
291 : Base(i_source_allocator)
306 : Base(
std::move(i_source_allocator))
308 static_assert(std::is_nothrow_move_constructible<ALLOCATOR_TYPE>::value,
"");
323 const ALLOCATOR_TYPE & i_source_allocator,
const BUSY_WAIT_FUNC & i_source_wait) noexcept
327 std::integral_constant<bool, PROD_CARDINALITY == concurrency_multiple>())
343 ALLOCATOR_TYPE && i_source_allocator,
const BUSY_WAIT_FUNC & i_source_wait) noexcept
345 std::move(i_source_allocator),
347 std::integral_constant<bool, PROD_CARDINALITY == concurrency_multiple>())
349 static_assert(std::is_nothrow_move_constructible<ALLOCATOR_TYPE>::value,
"");
364 const ALLOCATOR_TYPE & i_source_allocator, BUSY_WAIT_FUNC && i_source_wait) noexcept
367 std::move(i_source_wait),
370 static_assert(std::is_nothrow_move_constructible<BUSY_WAIT_FUNC>::value,
"");
385 ALLOCATOR_TYPE && i_source_allocator, BUSY_WAIT_FUNC && i_source_wait) noexcept
387 std::move(i_source_allocator),
388 std::move(i_source_wait),
391 static_assert(std::is_nothrow_move_constructible<ALLOCATOR_TYPE>::value,
"");
392 static_assert(std::is_nothrow_move_constructible<BUSY_WAIT_FUNC>::value,
"");
420 swap(*
this, i_source);
448 swap(static_cast<Base &>(i_first), static_cast<Base &>(i_second));
461 consume.begin_iteration(
this);
462 if (!consume.empty())
464 consume.clean_dead_elements();
474 bool empty() const noexcept {
return Consume().is_queue_empty(
this); }
485 consume_operation consume;
486 while (try_start_consume(consume))
517 ELEMENT_COMPLETE_TYPE,
518 typename std::decay<ELEMENT_COMPLETE_TYPE>::type>::value,
544 typename =
typename std::enable_if<
545 std::is_same<OTHERTYPE, ELEMENT_COMPLETE_TYPE>::value ||
546 std::is_void<ELEMENT_COMPLETE_TYPE>::value>::type>
548 : m_put(i_source.m_put), m_queue(i_source.m_queue)
550 i_source.m_put.m_user_storage =
nullptr;
560 typename =
typename std::enable_if<
561 std::is_same<OTHERTYPE, ELEMENT_COMPLETE_TYPE>::value ||
562 std::is_void<ELEMENT_COMPLETE_TYPE>::value>::type>
566 swap(m_put, i_source.m_put);
567 swap(m_queue, i_source.m_queue);
577 swap(i_first.m_put, i_second.m_put);
578 swap(i_first.m_queue, i_second.m_queue);
607 m_queue->template try_inplace_allocate_impl<detail::LfQueue_Throwing>(
608 detail::LfQueue_Dead,
false, i_size, i_alignment);
609 return push_data.m_user_storage;
636 template <
typename INPUT_ITERATOR>
637 typename std::iterator_traits<INPUT_ITERATOR>::value_type *
640 using ValueType =
typename std::iterator_traits<INPUT_ITERATOR>::value_type;
642 std::is_trivially_destructible<ValueType>::value,
643 "raw_allocate_copy provides a raw memory in-place allocation that does not " 645 "destructors when deallocating");
647 auto const count_s = std::distance(i_begin, i_end);
648 auto const count =
static_cast<size_t>(count_s);
651 auto const elements =
static_cast<ValueType *
>(
652 raw_allocate(
sizeof(ValueType) * count,
alignof(ValueType)));
653 for (
auto curr = elements; i_begin != i_end; ++i_begin, ++curr)
654 new (curr) ValueType(*i_begin);
680 template <
typename INPUT_RANGE>
682 -> decltype(std::declval<put_transaction>().raw_allocate_copy(
683 std::begin(i_source_range), std::end(i_source_range)))
685 return raw_allocate_copy(std::begin(i_source_range), std::end(i_source_range));
722 auto push_data = m_queue->try_inplace_allocate(
723 i_progress_guarantee, detail::LfQueue_Dead,
false, i_size, i_alignment);
724 return push_data.m_user_storage;
760 template <
typename INPUT_ITERATOR>
763 INPUT_ITERATOR i_begin,
765 i_end) noexcept(
std::
766 is_nothrow_copy_constructible<
typename std::iterator_traits<
767 INPUT_ITERATOR>::value_type>::value)
769 using ValueType =
typename std::iterator_traits<INPUT_ITERATOR>::value_type;
771 std::is_trivially_destructible<ValueType>::value,
772 "raw_allocate_copy provides a raw memory in-place allocation that does not " 774 "destructors when deallocating");
776 auto const count_s = std::distance(i_begin, i_end);
777 auto const count =
static_cast<size_t>(count_s);
780 auto const elements =
static_cast<ValueType *
>(try_raw_allocate(
781 i_progress_guarantee,
sizeof(ValueType) * count,
alignof(ValueType)));
782 if (elements !=
nullptr)
784 for (
auto curr = elements; i_begin != i_end; ++i_begin, ++curr)
785 new (curr) ValueType(*i_begin);
821 template <
typename INPUT_RANGE>
824 const INPUT_RANGE & i_source_range) noexcept(noexcept(std::declval<put_transaction>()
825 .try_raw_allocate_copy(
826 i_progress_guarantee,
827 std::begin(i_source_range),
828 std::end(i_source_range))))
829 -> decltype(std::declval<put_transaction>().try_raw_allocate_copy(
830 i_progress_guarantee, std::begin(i_source_range), std::end(i_source_range)))
832 return try_raw_allocate_copy(
833 i_progress_guarantee, std::begin(i_source_range), std::end(i_source_range));
847 Base::commit_put_impl(m_put);
848 m_put.m_user_storage =
nullptr;
864 Base::cancel_put_impl(m_put);
865 m_put.m_user_storage =
nullptr;
871 bool empty() const noexcept {
return m_put.m_user_storage ==
nullptr; }
876 explicit operator bool() const noexcept {
return m_put.m_user_storage !=
nullptr; }
883 return m_put.m_user_storage !=
nullptr ? m_queue :
nullptr;
900 return m_put.m_user_storage;
916 #ifndef DOXYGEN_DOC_GENERATION 918 typename EL = ELEMENT_COMPLETE_TYPE,
919 typename std::enable_if<!std::is_void<EL>::value>::type * =
nullptr>
922 ELEMENT_COMPLETE_TYPE &
926 return *
static_cast<ELEMENT_COMPLETE_TYPE *
>(element_ptr());
938 return *Base::type_after_control(m_put.m_control_block);
946 if (m_put.m_user_storage !=
nullptr)
948 Base::cancel_put_impl(m_put);
954 PrivateType,
sp_heter_queue * i_queue,
const Allocation & i_put) noexcept
955 : m_put(i_put), m_queue(i_queue)
1015 if (!m_consume_data.empty())
1017 m_consume_data.cancel_consume_impl();
1026 i_first.m_consume_data.swap(i_second.m_consume_data);
1037 explicit operator bool() const noexcept {
return !m_consume_data.
empty(); }
1059 auto const & type = complete_type();
1060 auto const element = element_ptr();
1061 type.destroy(element);
1063 type.RUNTIME_TYPE::~RUNTIME_TYPE();
1065 m_consume_data.commit_consume_impl();
1089 bool destroy_type = !std::is_trivially_destructible<RUNTIME_TYPE>::value;
1092 auto const & type = complete_type();
1093 type.RUNTIME_TYPE::~RUNTIME_TYPE();
1096 m_consume_data.commit_consume_impl();
1112 m_consume_data.cancel_consume_impl();
1123 return *Base::type_after_control(m_consume_data.m_control);
1136 return Base::get_unaligned_element(
1137 m_consume_data.m_control, m_consume_data.external());
1150 return Base::get_element(m_consume_data.m_control, m_consume_data.external());
1159 template <
typename COMPLETE_ELEMENT_TYPE>
1162 DENSITY_ASSERT(!empty() && complete_type().
template is<COMPLETE_ELEMENT_TYPE>());
1163 return *
static_cast<COMPLETE_ELEMENT_TYPE *
>(
1164 Base::get_element(m_consume_data.m_control, m_consume_data.external()));
1170 m_consume_data.start_consume_impl(i_queue);
1176 if (!m_consume_data.empty())
1178 m_consume_data.cancel_consume_impl();
1181 m_consume_data.start_consume_impl(i_queue);
1183 return !m_consume_data.empty();
1187 Consume m_consume_data;
1207 template <
typename ELEMENT_TYPE>
void push(ELEMENT_TYPE && i_source)
1209 return emplace<typename std::decay<ELEMENT_TYPE>::type>(
1210 std::forward<ELEMENT_TYPE>(i_source));
1229 template <
typename ELEMENT_TYPE,
typename... CONSTRUCTION_PARAMS>
1230 void emplace(CONSTRUCTION_PARAMS &&... i_construction_params)
1232 start_emplace<ELEMENT_TYPE>(std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...)
1252 void dyn_push(
const runtime_type & i_type) { start_dyn_push(i_type).commit(); }
1274 start_dyn_push_copy(i_type, i_source).commit();
1297 start_dyn_push_move(i_type, i_source).commit();
1324 template <
typename ELEMENT_TYPE>
1325 put_transaction<typename std::decay<ELEMENT_TYPE>::type>
1328 return start_emplace<typename std::decay<ELEMENT_TYPE>::type>(
1329 std::forward<ELEMENT_TYPE>(i_source));
1354 template <
typename ELEMENT_TYPE,
typename... CONSTRUCTION_PARAMS>
1355 put_transaction<ELEMENT_TYPE>
start_emplace(CONSTRUCTION_PARAMS &&... i_construction_params)
1357 auto push_data = Base::template try_inplace_allocate_impl<
1358 detail::LfQueue_Throwing,
1359 detail::LfQueue_Busy,
1361 detail::size_of<ELEMENT_TYPE>::value,
1362 alignof(ELEMENT_TYPE)>();
1364 runtime_type * type =
nullptr;
1367 auto const type_storage = Base::type_after_control(push_data.m_control_block);
1369 type =
new (type_storage) runtime_type(runtime_type::template make<ELEMENT_TYPE>());
1372 new (push_data.m_user_storage)
1373 ELEMENT_TYPE(std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...);
1377 if (type !=
nullptr)
1378 type->RUNTIME_TYPE::~RUNTIME_TYPE();
1380 Base::cancel_put_nodestroy_impl(push_data);
1384 return put_transaction<ELEMENT_TYPE>(PrivateType(),
this, push_data);
1407 auto push_data = Base::template try_inplace_allocate_impl<detail::LfQueue_Throwing>(
1408 detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
1410 runtime_type * type =
nullptr;
1413 auto const type_storage = Base::type_after_control(push_data.m_control_block);
1415 type =
new (type_storage) runtime_type(i_type);
1418 i_type.default_construct(push_data.m_user_storage);
1422 if (type !=
nullptr)
1423 type->RUNTIME_TYPE::~RUNTIME_TYPE();
1425 Base::cancel_put_nodestroy_impl(push_data);
1429 return put_transaction<void>(PrivateType(),
this, push_data);
1455 auto push_data = Base::template try_inplace_allocate_impl<detail::LfQueue_Throwing>(
1456 detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
1458 runtime_type * type =
nullptr;
1461 auto const type_storage = Base::type_after_control(push_data.m_control_block);
1463 type =
new (type_storage) runtime_type(i_type);
1466 i_type.copy_construct(push_data.m_user_storage, i_source);
1470 if (type !=
nullptr)
1471 type->RUNTIME_TYPE::~RUNTIME_TYPE();
1472 Base::cancel_put_nodestroy_impl(push_data);
1476 return put_transaction<void>(PrivateType(),
this, push_data);
1501 auto push_data = Base::template try_inplace_allocate_impl<detail::LfQueue_Throwing>(
1502 detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
1504 runtime_type * type =
nullptr;
1507 auto const type_storage = Base::type_after_control(push_data.m_control_block);
1509 type =
new (type_storage) runtime_type(i_type);
1512 i_type.move_construct(push_data.m_user_storage, i_source);
1516 if (type !=
nullptr)
1517 type->RUNTIME_TYPE::~RUNTIME_TYPE();
1518 Base::cancel_put_nodestroy_impl(push_data);
1522 return put_transaction<void>(PrivateType(),
this, push_data);
1551 template <
typename ELEMENT_TYPE>
1554 .template try_emplace<typename
std::decay<ELEMENT_TYPE>::type>(
1555 i_progress_guarantee,
std::forward<ELEMENT_TYPE>(i_source))))
1557 return try_emplace<typename std::decay<ELEMENT_TYPE>::type>(
1558 i_progress_guarantee, std::forward<ELEMENT_TYPE>(i_source));
1586 template <
typename ELEMENT_TYPE,
typename... CONSTRUCTION_PARAMS>
1589 noexcept(
std::declval<
sp_heter_queue>().template try_start_emplace<ELEMENT_TYPE>(
1590 i_progress_guarantee,
std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...)))
1592 auto tranasction = try_start_emplace<ELEMENT_TYPE>(
1593 i_progress_guarantee, std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...);
1596 tranasction.commit();
1626 auto tranasction = try_start_dyn_push(i_progress_guarantee, i_type);
1629 tranasction.commit();
1661 const runtime_type & i_type,
1662 const void * i_source)
1664 auto tranasction = try_start_dyn_push_copy(i_progress_guarantee, i_type, i_source);
1667 tranasction.commit();
1698 progress_guarantee i_progress_guarantee,
const runtime_type & i_type,
void * i_source)
1700 auto tranasction = try_start_dyn_push_move(i_progress_guarantee, i_type, i_source);
1703 tranasction.commit();
1739 template <
typename ELEMENT_TYPE>
1743 .template try_start_emplace<
1744 typename
std::decay<ELEMENT_TYPE>::type>(
1745 i_progress_guarantee,
1746 std::forward<ELEMENT_TYPE>(i_source))))
1748 return try_start_emplace<typename std::decay<ELEMENT_TYPE>::type>(
1749 i_progress_guarantee, std::forward<ELEMENT_TYPE>(i_source));
1782 template <
typename ELEMENT_TYPE,
typename... CONSTRUCTION_PARAMS>
1783 put_transaction<ELEMENT_TYPE>
1785 noexcept(ELEMENT_TYPE(
std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...)) &&
1786 noexcept(runtime_type(runtime_type::template make<ELEMENT_TYPE>())))
1788 auto push_data = Base::template try_inplace_allocate<
1789 detail::LfQueue_Busy,
1791 detail::size_of<ELEMENT_TYPE>::value,
1792 alignof(ELEMENT_TYPE)>(i_progress_guarantee);
1793 if (push_data.m_user_storage ==
nullptr)
1795 return put_transaction<ELEMENT_TYPE>();
1798 constexpr
bool is_noexcept =
1799 std::is_nothrow_constructible<ELEMENT_TYPE, CONSTRUCTION_PARAMS...>::value &&
1800 noexcept(runtime_type(runtime_type::template make<ELEMENT_TYPE>()));
1802 runtime_type * type =
nullptr;
1806 auto const type_storage = Base::type_after_control(push_data.m_control_block);
1808 type =
new (type_storage) runtime_type(runtime_type::template make<ELEMENT_TYPE>());
1811 new (push_data.m_user_storage)
1812 ELEMENT_TYPE(std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...);
1818 auto const type_storage = Base::type_after_control(push_data.m_control_block);
1821 new (type_storage) runtime_type(runtime_type::template make<ELEMENT_TYPE>());
1824 new (push_data.m_user_storage)
1825 ELEMENT_TYPE(std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...);
1829 if (type !=
nullptr)
1830 type->RUNTIME_TYPE::~RUNTIME_TYPE();
1832 Base::cancel_put_nodestroy_impl(push_data);
1833 DENSITY_INTERNAL_RETHROW_FROM_NOEXCEPT
1837 return put_transaction<ELEMENT_TYPE>(PrivateType(),
this, push_data);
1869 auto push_data = Base::try_inplace_allocate(
1870 i_progress_guarantee, detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
1871 if (push_data.m_user_storage ==
nullptr)
1873 return put_transaction<>();
1876 runtime_type * type =
nullptr;
1879 auto const type_storage = Base::type_after_control(push_data.m_control_block);
1881 type =
new (type_storage) runtime_type(i_type);
1884 i_type.default_construct(push_data.m_user_storage);
1888 if (type !=
nullptr)
1889 type->RUNTIME_TYPE::~RUNTIME_TYPE();
1891 Base::cancel_put_nodestroy_impl(push_data);
1895 return put_transaction<void>(PrivateType(),
this, push_data);
1929 const runtime_type & i_type,
1930 const void * i_source)
1932 auto push_data = Base::try_inplace_allocate(
1933 i_progress_guarantee, detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
1934 if (push_data.m_user_storage ==
nullptr)
1936 return put_transaction<>();
1939 runtime_type * type =
nullptr;
1942 auto const type_storage = Base::type_after_control(push_data.m_control_block);
1944 type =
new (type_storage) runtime_type(i_type);
1947 i_type.copy_construct(push_data.m_user_storage, i_source);
1951 if (type !=
nullptr)
1952 type->RUNTIME_TYPE::~RUNTIME_TYPE();
1953 Base::cancel_put_nodestroy_impl(push_data);
1957 return put_transaction<void>(PrivateType(),
this, push_data);
1989 progress_guarantee i_progress_guarantee,
const runtime_type & i_type,
void * i_source)
1991 auto push_data = Base::try_inplace_allocate(
1992 i_progress_guarantee, detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
1993 if (push_data.m_user_storage ==
nullptr)
1995 return put_transaction<>();
1998 runtime_type * type =
nullptr;
2001 auto const type_storage = Base::type_after_control(push_data.m_control_block);
2003 type =
new (type_storage) runtime_type(i_type);
2006 i_type.move_construct(push_data.m_user_storage, i_source);
2010 if (type !=
nullptr)
2011 type->RUNTIME_TYPE::~RUNTIME_TYPE();
2012 Base::cancel_put_nodestroy_impl(push_data);
2016 return put_transaction<void>(PrivateType(),
this, push_data);
2031 if (
auto operation = try_start_consume())
2047 return consume_operation(PrivateType(),
this);
2065 return i_consume.start_consume_impl(PrivateType(),
this);
2094 ELEMENT_COMPLETE_TYPE,
2095 typename std::decay<ELEMENT_COMPLETE_TYPE>::type>::value,
2121 typename =
typename std::enable_if<
2122 std::is_same<OTHERTYPE, ELEMENT_COMPLETE_TYPE>::value ||
2123 std::is_void<ELEMENT_COMPLETE_TYPE>::value>::type>
2125 : m_put(i_source.m_put), m_queue(i_source.m_queue)
2127 i_source.m_put.m_user_storage =
nullptr;
2137 typename =
typename std::enable_if<
2138 std::is_same<OTHERTYPE, ELEMENT_COMPLETE_TYPE>::value ||
2139 std::is_void<ELEMENT_COMPLETE_TYPE>::value>::type>
2144 swap(m_put, i_source.m_put);
2145 swap(m_queue, i_source.m_queue);
2156 swap(i_first.m_put, i_second.m_put);
2157 swap(i_first.m_queue, i_second.m_queue);
2186 m_queue->template try_inplace_allocate_impl<detail::LfQueue_Throwing>(
2187 detail::LfQueue_Dead,
false, i_size, i_alignment);
2188 return push_data.m_user_storage;
2215 template <
typename INPUT_ITERATOR>
2216 typename std::iterator_traits<INPUT_ITERATOR>::value_type *
2219 using ValueType =
typename std::iterator_traits<INPUT_ITERATOR>::value_type;
2221 std::is_trivially_destructible<ValueType>::value,
2222 "raw_allocate_copy provides a raw memory in-place allocation that does not " 2224 "destructors when deallocating");
2226 auto const count_s = std::distance(i_begin, i_end);
2227 auto const count =
static_cast<size_t>(count_s);
2228 DENSITY_ASSUME(
static_cast<decltype(count_s)
>(count) == count_s);
2230 auto const elements =
static_cast<ValueType *
>(
2231 raw_allocate(
sizeof(ValueType) * count,
alignof(ValueType)));
2232 for (
auto curr = elements; i_begin != i_end; ++i_begin, ++curr)
2233 new (curr) ValueType(*i_begin);
2259 template <
typename INPUT_RANGE>
2261 -> decltype(std::declval<reentrant_put_transaction>().raw_allocate_copy(
2262 std::begin(i_source_range), std::end(i_source_range)))
2264 return raw_allocate_copy(std::begin(i_source_range), std::end(i_source_range));
2301 auto push_data = m_queue->try_inplace_allocate(
2302 i_progress_guarantee, detail::LfQueue_Dead,
false, i_size, i_alignment);
2303 return push_data.m_user_storage;
2339 template <
typename INPUT_ITERATOR>
2342 INPUT_ITERATOR i_begin,
2344 i_end) noexcept(
std::
2345 is_nothrow_copy_constructible<
typename std::iterator_traits<
2346 INPUT_ITERATOR>::value_type>::value)
2348 using ValueType =
typename std::iterator_traits<INPUT_ITERATOR>::value_type;
2350 std::is_trivially_destructible<ValueType>::value,
2351 "raw_allocate_copy provides a raw memory in-place allocation that does not " 2353 "destructors when deallocating");
2355 auto const count_s = std::distance(i_begin, i_end);
2356 auto const count =
static_cast<size_t>(count_s);
2357 DENSITY_ASSUME(
static_cast<decltype(count_s)
>(count) == count_s);
2359 auto const elements =
static_cast<ValueType *
>(try_raw_allocate(
2360 i_progress_guarantee,
sizeof(ValueType) * count,
alignof(ValueType)));
2361 if (elements !=
nullptr)
2363 for (
auto curr = elements; i_begin != i_end; ++i_begin, ++curr)
2364 new (curr) ValueType(*i_begin);
2400 template <
typename INPUT_RANGE>
2404 i_source_range) noexcept(noexcept(std::declval<reentrant_put_transaction>()
2405 .try_raw_allocate_copy(
2406 i_progress_guarantee,
2407 std::begin(i_source_range),
2408 std::end(i_source_range))))
2409 -> decltype(std::declval<reentrant_put_transaction>().try_raw_allocate_copy(
2410 i_progress_guarantee, std::begin(i_source_range), std::end(i_source_range)))
2412 return try_raw_allocate_copy(
2413 i_progress_guarantee, std::begin(i_source_range), std::end(i_source_range));
2427 Base::commit_put_impl(m_put);
2428 m_put.m_user_storage =
nullptr;
2444 Base::cancel_put_impl(m_put);
2445 m_put.m_user_storage =
nullptr;
2451 bool empty() const noexcept {
return m_put.m_user_storage ==
nullptr; }
2456 explicit operator bool() const noexcept {
return m_put.m_user_storage !=
nullptr; }
2463 return m_put.m_user_storage !=
nullptr ? m_queue :
nullptr;
2480 return m_put.m_user_storage;
2496 #ifndef DOXYGEN_DOC_GENERATION 2498 typename EL = ELEMENT_COMPLETE_TYPE,
2499 typename std::enable_if<!std::is_void<EL>::value>::type * =
nullptr>
2502 ELEMENT_COMPLETE_TYPE &
2506 return *
static_cast<ELEMENT_COMPLETE_TYPE *
>(element_ptr());
2518 return *Base::type_after_control(m_put.m_control_block);
2526 if (m_put.m_user_storage !=
nullptr)
2528 Base::cancel_put_impl(m_put);
2534 PrivateType,
sp_heter_queue * i_queue,
const Allocation & i_put) noexcept
2535 : m_put(i_put), m_queue(i_queue)
2596 if (!m_consume_data.empty())
2598 m_consume_data.cancel_consume_impl();
2609 i_first.m_consume_data.swap(i_second.m_consume_data);
2620 explicit operator bool() const noexcept {
return !m_consume_data.
empty(); }
2642 auto const & type = complete_type();
2643 auto const element = element_ptr();
2644 type.destroy(element);
2646 type.RUNTIME_TYPE::~RUNTIME_TYPE();
2648 m_consume_data.commit_consume_impl();
2672 bool destroy_type = !std::is_trivially_destructible<RUNTIME_TYPE>::value;
2675 auto const & type = complete_type();
2676 type.RUNTIME_TYPE::~RUNTIME_TYPE();
2679 m_consume_data.commit_consume_impl();
2695 m_consume_data.cancel_consume_impl();
2706 return *Base::type_after_control(m_consume_data.m_control);
2719 return Base::get_unaligned_element(
2720 m_consume_data.m_control, m_consume_data.external());
2733 return Base::get_element(m_consume_data.m_control, m_consume_data.external());
2742 template <
typename COMPLETE_ELEMENT_TYPE>
2745 DENSITY_ASSERT(!empty() && complete_type().
template is<COMPLETE_ELEMENT_TYPE>());
2746 return *
static_cast<COMPLETE_ELEMENT_TYPE *
>(
2747 Base::get_element(m_consume_data.m_control, m_consume_data.external()));
2753 m_consume_data.start_consume_impl(i_queue);
2759 if (!m_consume_data.empty())
2761 m_consume_data.cancel_consume_impl();
2764 m_consume_data.start_consume_impl(i_queue);
2766 return !m_consume_data.empty();
2770 Consume m_consume_data;
2780 return reentrant_emplace<typename std::decay<ELEMENT_TYPE>::type>(
2781 std::forward<ELEMENT_TYPE>(i_source));
2789 template <
typename ELEMENT_TYPE,
typename... CONSTRUCTION_PARAMS>
2792 start_reentrant_emplace<ELEMENT_TYPE>(
2793 std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...)
2804 start_reentrant_dyn_push(i_type).commit();
2814 start_reentrant_dyn_push_copy(i_type, i_source).commit();
2824 start_reentrant_dyn_push_move(i_type, i_source).commit();
2832 template <
typename ELEMENT_TYPE>
2833 reentrant_put_transaction<typename std::decay<ELEMENT_TYPE>::type>
2836 return start_reentrant_emplace<typename std::decay<ELEMENT_TYPE>::type>(
2837 std::forward<ELEMENT_TYPE>(i_source));
2845 template <
typename ELEMENT_TYPE,
typename... CONSTRUCTION_PARAMS>
2846 reentrant_put_transaction<ELEMENT_TYPE>
2849 auto push_data = Base::template try_inplace_allocate_impl<
2850 detail::LfQueue_Throwing,
2851 detail::LfQueue_Busy,
2853 detail::size_of<ELEMENT_TYPE>::value,
2854 alignof(ELEMENT_TYPE)>();
2856 runtime_type * type =
nullptr;
2859 auto const type_storage = Base::type_after_control(push_data.m_control_block);
2861 type =
new (type_storage) runtime_type(runtime_type::template make<ELEMENT_TYPE>());
2864 new (push_data.m_user_storage)
2865 ELEMENT_TYPE(std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...);
2869 if (type !=
nullptr)
2870 type->RUNTIME_TYPE::~RUNTIME_TYPE();
2871 Base::cancel_put_nodestroy_impl(push_data);
2875 return reentrant_put_transaction<ELEMENT_TYPE>(PrivateType(),
this, push_data);
2885 auto push_data = Base::template try_inplace_allocate_impl<detail::LfQueue_Throwing>(
2886 detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
2888 runtime_type * type =
nullptr;
2891 auto const type_storage = Base::type_after_control(push_data.m_control_block);
2893 type =
new (type_storage) runtime_type(i_type);
2896 i_type.default_construct(push_data.m_user_storage);
2900 if (type !=
nullptr)
2901 type->RUNTIME_TYPE::~RUNTIME_TYPE();
2902 Base::cancel_put_nodestroy_impl(push_data);
2906 return reentrant_put_transaction<void>(PrivateType(),
this, push_data);
2915 reentrant_put_transaction<>
2918 auto push_data = Base::template try_inplace_allocate_impl<detail::LfQueue_Throwing>(
2919 detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
2921 runtime_type * type =
nullptr;
2924 auto const type_storage = Base::type_after_control(push_data.m_control_block);
2926 type =
new (type_storage) runtime_type(i_type);
2929 i_type.copy_construct(push_data.m_user_storage, i_source);
2933 if (type !=
nullptr)
2934 type->RUNTIME_TYPE::~RUNTIME_TYPE();
2935 Base::cancel_put_nodestroy_impl(push_data);
2939 return reentrant_put_transaction<void>(PrivateType(),
this, push_data);
2947 reentrant_put_transaction<>
2950 auto push_data = Base::template try_inplace_allocate_impl<detail::LfQueue_Throwing>(
2951 detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
2953 runtime_type * type =
nullptr;
2956 auto const type_storage = Base::type_after_control(push_data.m_control_block);
2958 type =
new (type_storage) runtime_type(i_type);
2961 i_type.move_construct(push_data.m_user_storage, i_source);
2965 if (type !=
nullptr)
2966 type->RUNTIME_TYPE::~RUNTIME_TYPE();
2967 Base::cancel_put_nodestroy_impl(push_data);
2971 return reentrant_put_transaction<void>(PrivateType(),
this, push_data);
2979 template <
typename ELEMENT_TYPE>
2983 .template try_reentrant_emplace<
2984 typename
std::decay<ELEMENT_TYPE>::type>(
2985 i_progress_guarantee,
2986 std::forward<ELEMENT_TYPE>(i_source))))
2988 return try_reentrant_emplace<typename std::decay<ELEMENT_TYPE>::type>(
2989 i_progress_guarantee, std::forward<ELEMENT_TYPE>(i_source));
2997 template <
typename ELEMENT_TYPE,
typename... CONSTRUCTION_PARAMS>
3001 std::declval<
sp_heter_queue>().template try_start_reentrant_emplace<ELEMENT_TYPE>(
3002 i_progress_guarantee,
std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...)))
3004 auto tranasction = try_start_reentrant_emplace<ELEMENT_TYPE>(
3005 i_progress_guarantee, std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...);
3008 tranasction.commit();
3020 auto tranasction = try_start_reentrant_dyn_push(i_progress_guarantee, i_type);
3023 tranasction.commit();
3034 const runtime_type & i_type,
3035 const void * i_source)
3038 try_start_reentrant_dyn_push_copy(i_progress_guarantee, i_type, i_source);
3041 tranasction.commit();
3051 progress_guarantee i_progress_guarantee,
const runtime_type & i_type,
void * i_source)
3054 try_start_reentrant_dyn_push_move(i_progress_guarantee, i_type, i_source);
3057 tranasction.commit();
3066 template <
typename ELEMENT_TYPE>
3070 .template try_start_reentrant_emplace<
3071 typename
std::decay<ELEMENT_TYPE>::type>(
3072 i_progress_guarantee,
3073 std::forward<ELEMENT_TYPE>(i_source))))
3075 return try_start_reentrant_emplace<typename std::decay<ELEMENT_TYPE>::type>(
3076 i_progress_guarantee, std::forward<ELEMENT_TYPE>(i_source));
3084 template <
typename ELEMENT_TYPE,
typename... CONSTRUCTION_PARAMS>
3085 reentrant_put_transaction<ELEMENT_TYPE>
3087 noexcept(ELEMENT_TYPE(
std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...)) &&
3088 noexcept(runtime_type(runtime_type::template make<ELEMENT_TYPE>())))
3090 auto push_data = Base::template try_inplace_allocate<
3091 detail::LfQueue_Busy,
3093 detail::size_of<ELEMENT_TYPE>::value,
3094 alignof(ELEMENT_TYPE)>(i_progress_guarantee);
3095 if (push_data.m_user_storage ==
nullptr)
3097 return reentrant_put_transaction<ELEMENT_TYPE>();
3100 constexpr
bool is_noexcept =
3101 std::is_nothrow_constructible<ELEMENT_TYPE, CONSTRUCTION_PARAMS...>::value &&
3102 noexcept(runtime_type(runtime_type::template make<ELEMENT_TYPE>()));
3104 runtime_type * type =
nullptr;
3108 auto const type_storage = Base::type_after_control(push_data.m_control_block);
3110 type =
new (type_storage) runtime_type(runtime_type::template make<ELEMENT_TYPE>());
3113 new (push_data.m_user_storage)
3114 ELEMENT_TYPE(std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...);
3120 auto const type_storage = Base::type_after_control(push_data.m_control_block);
3123 new (type_storage) runtime_type(runtime_type::template make<ELEMENT_TYPE>());
3126 new (push_data.m_user_storage)
3127 ELEMENT_TYPE(std::forward<CONSTRUCTION_PARAMS>(i_construction_params)...);
3131 if (type !=
nullptr)
3132 type->RUNTIME_TYPE::~RUNTIME_TYPE();
3134 Base::cancel_put_nodestroy_impl(push_data);
3135 DENSITY_INTERNAL_RETHROW_FROM_NOEXCEPT
3139 return reentrant_put_transaction<ELEMENT_TYPE>(PrivateType(),
this, push_data);
3150 auto push_data = Base::try_inplace_allocate(
3151 i_progress_guarantee, detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
3152 if (push_data.m_user_storage ==
nullptr)
3154 return reentrant_put_transaction<>();
3157 runtime_type * type =
nullptr;
3160 auto const type_storage = Base::type_after_control(push_data.m_control_block);
3162 type =
new (type_storage) runtime_type(i_type);
3165 i_type.default_construct(push_data.m_user_storage);
3169 if (type !=
nullptr)
3170 type->RUNTIME_TYPE::~RUNTIME_TYPE();
3172 Base::cancel_put_nodestroy_impl(push_data);
3176 return reentrant_put_transaction<void>(PrivateType(),
this, push_data);
3186 const runtime_type & i_type,
3187 const void * i_source)
3189 auto push_data = Base::try_inplace_allocate(
3190 i_progress_guarantee, detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
3191 if (push_data.m_user_storage ==
nullptr)
3193 return reentrant_put_transaction<>();
3196 runtime_type * type =
nullptr;
3199 auto const type_storage = Base::type_after_control(push_data.m_control_block);
3201 type =
new (type_storage) runtime_type(i_type);
3204 i_type.copy_construct(push_data.m_user_storage, i_source);
3208 if (type !=
nullptr)
3209 type->RUNTIME_TYPE::~RUNTIME_TYPE();
3210 Base::cancel_put_nodestroy_impl(push_data);
3214 return reentrant_put_transaction<void>(PrivateType(),
this, push_data);
3223 progress_guarantee i_progress_guarantee,
const runtime_type & i_type,
void * i_source)
3225 auto push_data = Base::try_inplace_allocate(
3226 i_progress_guarantee, detail::LfQueue_Busy,
true, i_type.size(), i_type.alignment());
3227 if (push_data.m_user_storage ==
nullptr)
3229 return reentrant_put_transaction<>();
3232 runtime_type * type =
nullptr;
3235 auto const type_storage = Base::type_after_control(push_data.m_control_block);
3237 type =
new (type_storage) runtime_type(i_type);
3240 i_type.move_construct(push_data.m_user_storage, i_source);
3244 if (type !=
nullptr)
3245 type->RUNTIME_TYPE::~RUNTIME_TYPE();
3246 Base::cancel_put_nodestroy_impl(push_data);
3250 return reentrant_put_transaction<void>(PrivateType(),
this, push_data);
3266 if (
auto operation = try_start_reentrant_consume())
3285 return reentrant_consume_operation(PrivateType(),
this);
3305 return i_consume.start_consume_impl(PrivateType(),
this);
3312 #pragma warning(pop) ~reentrant_consume_operation()
Definition: sp_heter_queue.h:2594
void cancel() noexcept
Definition: sp_heter_queue.h:2441
reentrant_put_transaction start_reentrant_dyn_push_move(const runtime_type &i_type, void *i_source)
Definition: sp_heter_queue.h:2948
void reentrant_dyn_push_move(const runtime_type &i_type, void *i_source)
Definition: sp_heter_queue.h:2822
basic_default_allocator< default_page_capacity > default_allocator
Definition: default_allocator.h:152
sp_heter_queue & operator=(sp_heter_queue &&i_source) noexcept
Definition: sp_heter_queue.h:418
std::iterator_traits< INPUT_ITERATOR >::value_type * try_raw_allocate_copy(progress_guarantee i_progress_guarantee, INPUT_ITERATOR i_begin, INPUT_ITERATOR i_end) noexcept(std:: is_nothrow_copy_constructible< typename std::iterator_traits< INPUT_ITERATOR >::value_type >::value)
Definition: sp_heter_queue.h:2340
~put_transaction()
Definition: sp_heter_queue.h:944
Definition: sp_heter_queue.h:208
void cancel() noexcept
Definition: sp_heter_queue.h:2692
concurrency_cardinality
Definition: density_common.h:56
Definition: conc_function_queue.h:11
Definition: runtime_type.h:665
sp_heter_queue * queue() const noexcept
Definition: sp_heter_queue.h:2625
void * try_raw_allocate(progress_guarantee i_progress_guarantee, size_t i_size, size_t i_alignment) noexcept
Definition: sp_heter_queue.h:2297
friend void swap(reentrant_consume_operation &i_first, reentrant_consume_operation &i_second) noexcept
Definition: sp_heter_queue.h:2605
put_transaction & operator=(put_transaction< OTHERTYPE > &&i_source) noexcept
Definition: sp_heter_queue.h:563
void dyn_push(const runtime_type &i_type)
Definition: sp_heter_queue.h:1252
reentrant_put_transaction start_reentrant_dyn_push_copy(const runtime_type &i_type, const void *i_source)
Definition: sp_heter_queue.h:2916
auto raw_allocate_copy(const INPUT_RANGE &i_source_range) -> decltype(std::declval< reentrant_put_transaction >().raw_allocate_copy( std::begin(i_source_range), std::end(i_source_range)))
Definition: sp_heter_queue.h:2260
void commit() noexcept
Definition: sp_heter_queue.h:2424
ELEMENT_COMPLETE_TYPE & element() const noexcept
Definition: sp_heter_queue.h:2504
Definition: density_common.h:60
void operator()() noexcept
Definition: sp_heter_queue.h:51
void reentrant_push(ELEMENT_TYPE &&i_source)
Definition: sp_heter_queue.h:2778
reentrant_put_transaction try_start_reentrant_dyn_push_copy(progress_guarantee i_progress_guarantee, const runtime_type &i_type, const void *i_source)
Definition: sp_heter_queue.h:3184
void commit_nodestroy() noexcept
Definition: sp_heter_queue.h:2668
reentrant_put_transaction< typename std::decay< ELEMENT_TYPE >::type > start_reentrant_push(ELEMENT_TYPE &&i_source)
Definition: sp_heter_queue.h:2834
Definition: runtime_type.h:1061
void * element_ptr() const noexcept
Definition: sp_heter_queue.h:2477
sp_heter_queue * queue() const noexcept
Definition: sp_heter_queue.h:2461
auto raw_allocate_copy(const INPUT_RANGE &i_source_range) -> decltype(std::declval< put_transaction >().raw_allocate_copy( std::begin(i_source_range), std::end(i_source_range)))
Definition: sp_heter_queue.h:681
auto try_raw_allocate_copy(progress_guarantee i_progress_guarantee, const INPUT_RANGE &i_source_range) noexcept(noexcept(std::declval< reentrant_put_transaction >() .try_raw_allocate_copy( i_progress_guarantee, std::begin(i_source_range), std::end(i_source_range)))) -> decltype(std::declval< reentrant_put_transaction >().try_raw_allocate_copy( i_progress_guarantee, std::begin(i_source_range), std::end(i_source_range)))
Definition: sp_heter_queue.h:2401
const RUNTIME_TYPE & complete_type() const noexcept
Definition: sp_heter_queue.h:935
void * element_ptr() const noexcept
Definition: sp_heter_queue.h:1147
reentrant_put_transaction try_start_reentrant_dyn_push(progress_guarantee i_progress_guarantee, const runtime_type &i_type)
Definition: sp_heter_queue.h:3147
put_transaction start_dyn_push_copy(const runtime_type &i_type, const void *i_source)
Definition: sp_heter_queue.h:1453
Definition: density_common.h:58
reentrant_put_transaction start_reentrant_dyn_push(const runtime_type &i_type)
Definition: sp_heter_queue.h:2883
COMPLETE_ELEMENT_TYPE & element() const noexcept
Definition: sp_heter_queue.h:2743
allocator_type & get_allocator_ref() noexcept
Definition: sp_heter_queue.h:436
void dyn_push_copy(const runtime_type &i_type, const void *i_source)
Definition: sp_heter_queue.h:1272
friend void swap(put_transaction &i_first, put_transaction &i_second) noexcept
Definition: sp_heter_queue.h:574
void emplace(CONSTRUCTION_PARAMS &&...i_construction_params)
Definition: sp_heter_queue.h:1230
bool empty() const noexcept
Definition: sp_heter_queue.h:2615
bool try_dyn_push(progress_guarantee i_progress_guarantee, const runtime_type &i_type)
Definition: sp_heter_queue.h:1624
bool try_emplace(progress_guarantee i_progress_guarantee, CONSTRUCTION_PARAMS &&...i_construction_params) noexcept( noexcept(std::declval< sp_heter_queue >().template try_start_emplace< ELEMENT_TYPE >( i_progress_guarantee, std::forward< CONSTRUCTION_PARAMS >(i_construction_params)...)))
Definition: sp_heter_queue.h:1588
void clear() noexcept
Definition: sp_heter_queue.h:483
bool empty() const noexcept
Definition: sp_heter_queue.h:871
void commit() noexcept
Definition: sp_heter_queue.h:2638
#define DENSITY_ASSERT(...)
Definition: density_config.h:19
constexpr sp_heter_queue(const ALLOCATOR_TYPE &i_source_allocator, BUSY_WAIT_FUNC &&i_source_wait) noexcept
Definition: sp_heter_queue.h:363
void * raw_allocate(size_t i_size, size_t i_alignment)
Definition: sp_heter_queue.h:603
reentrant_put_transaction(reentrant_put_transaction< OTHERTYPE > &&i_source) noexcept
Definition: sp_heter_queue.h:2124
bool try_start_consume(consume_operation &i_consume) noexcept
Definition: sp_heter_queue.h:2063
put_transaction(put_transaction< OTHERTYPE > &&i_source) noexcept
Definition: sp_heter_queue.h:547
constexpr sp_heter_queue(ALLOCATOR_TYPE &&i_source_allocator, BUSY_WAIT_FUNC &&i_source_wait) noexcept
Definition: sp_heter_queue.h:384
void commit() noexcept
Definition: sp_heter_queue.h:844
friend void swap(reentrant_put_transaction &i_first, reentrant_put_transaction &i_second) noexcept
Definition: sp_heter_queue.h:2152
bool empty() const noexcept
Definition: sp_heter_queue.h:2451
constexpr sp_heter_queue(ALLOCATOR_TYPE &&i_source_allocator) noexcept
Definition: sp_heter_queue.h:305
allocator_type get_allocator() noexcept(std::is_nothrow_copy_constructible< allocator_type >::value)
Definition: sp_heter_queue.h:428
put_transaction< typename std::decay< ELEMENT_TYPE >::type > try_start_push(progress_guarantee i_progress_guarantee, ELEMENT_TYPE &&i_source) noexcept(noexcept(std::declval< sp_heter_queue >() .template try_start_emplace< typename std::decay< ELEMENT_TYPE >::type >( i_progress_guarantee, std::forward< ELEMENT_TYPE >(i_source))))
Definition: sp_heter_queue.h:1740
bool try_reentrant_emplace(progress_guarantee i_progress_guarantee, CONSTRUCTION_PARAMS &&...i_construction_params) noexcept( noexcept( std::declval< sp_heter_queue >().template try_start_reentrant_emplace< ELEMENT_TYPE >( i_progress_guarantee, std::forward< CONSTRUCTION_PARAMS >(i_construction_params)...)))
Definition: sp_heter_queue.h:2999
void commit() noexcept
Definition: sp_heter_queue.h:1055
constexpr sp_heter_queue(const ALLOCATOR_TYPE &i_source_allocator, const BUSY_WAIT_FUNC &i_source_wait) noexcept
Definition: sp_heter_queue.h:322
void * unaligned_element_ptr() const noexcept
Definition: sp_heter_queue.h:1133
Definition: sp_heter_queue.h:47
void commit_nodestroy() noexcept
Definition: sp_heter_queue.h:1085
bool try_pop() noexcept
Definition: sp_heter_queue.h:2029
ELEMENT_COMPLETE_TYPE & element() const noexcept
Definition: sp_heter_queue.h:924
bool try_reentrant_dyn_push(progress_guarantee i_progress_guarantee, const runtime_type &i_type)
Definition: sp_heter_queue.h:3017
~sp_heter_queue()
Definition: sp_heter_queue.h:456
COMPLETE_ELEMENT_TYPE & element() const noexcept
Definition: sp_heter_queue.h:1160
bool try_start_reentrant_consume(reentrant_consume_operation &i_consume) noexcept
Definition: sp_heter_queue.h:3303
bool empty() const noexcept
Definition: sp_heter_queue.h:1032
progress_guarantee
Definition: density_common.h:84
reentrant_put_transaction< typename std::decay< ELEMENT_TYPE >::type > try_start_reentrant_push(progress_guarantee i_progress_guarantee, ELEMENT_TYPE &&i_source) noexcept(noexcept(std::declval< sp_heter_queue >() .template try_start_reentrant_emplace< typename std::decay< ELEMENT_TYPE >::type >( i_progress_guarantee, std::forward< ELEMENT_TYPE >(i_source))))
Definition: sp_heter_queue.h:3067
bool try_reentrant_pop() noexcept
Definition: sp_heter_queue.h:3264
constexpr bool is_power_of_2(size_t i_number) noexcept
Definition: density_common.h:109
bool empty() const noexcept
Definition: sp_heter_queue.h:474
bool try_dyn_push_move(progress_guarantee i_progress_guarantee, const runtime_type &i_type, void *i_source)
Definition: sp_heter_queue.h:1697
void * try_raw_allocate(progress_guarantee i_progress_guarantee, size_t i_size, size_t i_alignment) noexcept
Definition: sp_heter_queue.h:718
void cancel() noexcept
Definition: sp_heter_queue.h:861
void cancel() noexcept
Definition: sp_heter_queue.h:1109
sp_heter_queue * queue() const noexcept
Definition: sp_heter_queue.h:881
const RUNTIME_TYPE & complete_type() const noexcept
Definition: sp_heter_queue.h:2515
bool try_reentrant_dyn_push_copy(progress_guarantee i_progress_guarantee, const runtime_type &i_type, const void *i_source)
Definition: sp_heter_queue.h:3032
const RUNTIME_TYPE & complete_type() const noexcept
Definition: sp_heter_queue.h:2703
void * raw_allocate(size_t i_size, size_t i_alignment)
Definition: sp_heter_queue.h:2182
reentrant_put_transaction< ELEMENT_TYPE > try_start_reentrant_emplace(progress_guarantee i_progress_guarantee, CONSTRUCTION_PARAMS &&...i_construction_params) noexcept( noexcept(ELEMENT_TYPE(std::forward< CONSTRUCTION_PARAMS >(i_construction_params)...))&& noexcept(runtime_type(runtime_type::template make< ELEMENT_TYPE >())))
Definition: sp_heter_queue.h:3086
std::iterator_traits< INPUT_ITERATOR >::value_type * raw_allocate_copy(INPUT_ITERATOR i_begin, INPUT_ITERATOR i_end)
Definition: sp_heter_queue.h:638
const allocator_type & get_allocator_ref() const noexcept
Definition: sp_heter_queue.h:441
void dyn_push_move(const runtime_type &i_type, void *i_source)
Definition: sp_heter_queue.h:1295
std::iterator_traits< INPUT_ITERATOR >::value_type * try_raw_allocate_copy(progress_guarantee i_progress_guarantee, INPUT_ITERATOR i_begin, INPUT_ITERATOR i_end) noexcept(std:: is_nothrow_copy_constructible< typename std::iterator_traits< INPUT_ITERATOR >::value_type >::value)
Definition: sp_heter_queue.h:761
std::iterator_traits< INPUT_ITERATOR >::value_type * raw_allocate_copy(INPUT_ITERATOR i_begin, INPUT_ITERATOR i_end)
Definition: sp_heter_queue.h:2217
bool try_reentrant_dyn_push_move(progress_guarantee i_progress_guarantee, const runtime_type &i_type, void *i_source)
Definition: sp_heter_queue.h:3050
Definition: sp_heter_queue.h:513
void reentrant_dyn_push_copy(const runtime_type &i_type, const void *i_source)
Definition: sp_heter_queue.h:2812
put_transaction try_start_dyn_push(progress_guarantee i_progress_guarantee, const runtime_type &i_type)
Definition: sp_heter_queue.h:1867
void push(ELEMENT_TYPE &&i_source)
Definition: sp_heter_queue.h:1207
put_transaction try_start_dyn_push_copy(progress_guarantee i_progress_guarantee, const runtime_type &i_type, const void *i_source)
Definition: sp_heter_queue.h:1927
void reentrant_dyn_push(const runtime_type &i_type)
Definition: sp_heter_queue.h:2802
sp_heter_queue * queue() const noexcept
Definition: sp_heter_queue.h:1042
~consume_operation()
Definition: sp_heter_queue.h:1013
Definition: sp_heter_queue.h:2562
const RUNTIME_TYPE & complete_type() const noexcept
Definition: sp_heter_queue.h:1120
Definition: sp_heter_queue.h:982
reentrant_put_transaction & operator=(reentrant_put_transaction< OTHERTYPE > &&i_source) noexcept
Definition: sp_heter_queue.h:2141
auto try_raw_allocate_copy(progress_guarantee i_progress_guarantee, const INPUT_RANGE &i_source_range) noexcept(noexcept(std::declval< put_transaction >() .try_raw_allocate_copy( i_progress_guarantee, std::begin(i_source_range), std::end(i_source_range)))) -> decltype(std::declval< put_transaction >().try_raw_allocate_copy( i_progress_guarantee, std::begin(i_source_range), std::end(i_source_range)))
Definition: sp_heter_queue.h:822
reentrant_consume_operation try_start_reentrant_consume() noexcept
Definition: sp_heter_queue.h:3283
consume_operation try_start_consume() noexcept
Definition: sp_heter_queue.h:2045
reentrant_put_transaction try_start_reentrant_dyn_push_move(progress_guarantee i_progress_guarantee, const runtime_type &i_type, void *i_source)
Definition: sp_heter_queue.h:3222
Definition: sp_heter_queue.h:2090
put_transaction< ELEMENT_TYPE > start_emplace(CONSTRUCTION_PARAMS &&...i_construction_params)
Definition: sp_heter_queue.h:1355
put_transaction start_dyn_push(const runtime_type &i_type)
Definition: sp_heter_queue.h:1405
friend void swap(sp_heter_queue &i_first, sp_heter_queue &i_second) noexcept
Definition: sp_heter_queue.h:446
bool try_push(progress_guarantee i_progress_guarantee, ELEMENT_TYPE &&i_source) noexcept( noexcept(std::declval< sp_heter_queue >() .template try_emplace< typename std::decay< ELEMENT_TYPE >::type >( i_progress_guarantee, std::forward< ELEMENT_TYPE >(i_source))))
Definition: sp_heter_queue.h:1552
put_transaction start_dyn_push_move(const runtime_type &i_type, void *i_source)
Definition: sp_heter_queue.h:1499
void reentrant_emplace(CONSTRUCTION_PARAMS &&...i_construction_params)
Definition: sp_heter_queue.h:2790
put_transaction< ELEMENT_TYPE > try_start_emplace(progress_guarantee i_progress_guarantee, CONSTRUCTION_PARAMS &&...i_construction_params) noexcept( noexcept(ELEMENT_TYPE(std::forward< CONSTRUCTION_PARAMS >(i_construction_params)...))&& noexcept(runtime_type(runtime_type::template make< ELEMENT_TYPE >())))
Definition: sp_heter_queue.h:1784
#define DENSITY_ASSUME(bool_expr,...)
Definition: density_config.h:46
bool try_dyn_push_copy(progress_guarantee i_progress_guarantee, const runtime_type &i_type, const void *i_source)
Definition: sp_heter_queue.h:1659
bool try_reentrant_push(progress_guarantee i_progress_guarantee, ELEMENT_TYPE &&i_source) noexcept(noexcept(std::declval< sp_heter_queue >() .template try_reentrant_emplace< typename std::decay< ELEMENT_TYPE >::type >( i_progress_guarantee, std::forward< ELEMENT_TYPE >(i_source))))
Definition: sp_heter_queue.h:2980
reentrant_put_transaction< ELEMENT_TYPE > start_reentrant_emplace(CONSTRUCTION_PARAMS &&...i_construction_params)
Definition: sp_heter_queue.h:2847
void * element_ptr() const noexcept
Definition: sp_heter_queue.h:897
put_transaction< typename std::decay< ELEMENT_TYPE >::type > start_push(ELEMENT_TYPE &&i_source)
Definition: sp_heter_queue.h:1326
void * unaligned_element_ptr() const noexcept
Definition: sp_heter_queue.h:2716
friend void swap(consume_operation &i_first, consume_operation &i_second) noexcept
Definition: sp_heter_queue.h:1024
~reentrant_put_transaction()
Definition: sp_heter_queue.h:2524
put_transaction try_start_dyn_push_move(progress_guarantee i_progress_guarantee, const runtime_type &i_type, void *i_source)
Definition: sp_heter_queue.h:1988
constexpr sp_heter_queue(ALLOCATOR_TYPE &&i_source_allocator, const BUSY_WAIT_FUNC &i_source_wait) noexcept
Definition: sp_heter_queue.h:342
void * element_ptr() const noexcept
Definition: sp_heter_queue.h:2730