mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
fix: MSVC error C2672
This commit is contained in:
parent
a7b8af7fa8
commit
4e05befbe9
@ -50,8 +50,8 @@ template <typename T>
|
|||||||
struct has_context_impl<T, ::LIBIMP::void_t<typename T::context_impl>>
|
struct has_context_impl<T, ::LIBIMP::void_t<typename T::context_impl>>
|
||||||
: std::true_type {};
|
: std::true_type {};
|
||||||
|
|
||||||
template <typename T, bool = has_header<T>{}
|
template <typename T, bool = has_header<T>::value
|
||||||
, bool = has_header_impl<T>{}>
|
, bool = has_header_impl<T>::value>
|
||||||
struct traits_header {
|
struct traits_header {
|
||||||
struct header {};
|
struct header {};
|
||||||
};
|
};
|
||||||
@ -66,8 +66,8 @@ struct traits_header<T, false, true> {
|
|||||||
using header = typename T::header_impl;
|
using header = typename T::header_impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, bool = has_context<T>{}
|
template <typename T, bool = has_context<T>::value
|
||||||
, bool = has_context_impl<T>{}>
|
, bool = has_context_impl<T>::value>
|
||||||
struct traits_context {
|
struct traits_context {
|
||||||
struct context {};
|
struct context {};
|
||||||
};
|
};
|
||||||
@ -112,13 +112,20 @@ class broadcast {};
|
|||||||
|
|
||||||
/// \brief Determines whether type T can be implicitly converted to type U.
|
/// \brief Determines whether type T can be implicitly converted to type U.
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
using is_convertible = typename std::enable_if<std::is_convertible<T *, U *>::value, bool>::type;
|
using convertible = std::enable_if_t<std::is_convertible<T *, U *>::value, bool>;
|
||||||
|
|
||||||
/// \brief Check whether the elems header type is valid.
|
/// \brief Check whether the elems header type is valid.
|
||||||
|
template <typename T, typename = void>
|
||||||
|
struct is_elems_header : std::false_type {};
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using is_elems_header = decltype(
|
struct is_elems_header<T, ::LIBIMP::void_t<
|
||||||
std::declval<index_t>() % std::declval<T>().circ_size,
|
decltype(std::declval<index_t>() % std::declval<T>().circ_size),
|
||||||
std::enable_if_t<std::is_convertible<decltype(std::declval<T>().valid()), bool>::value, bool>{});
|
std::enable_if_t<std::is_convertible<decltype(std::declval<T>().valid()), bool>::value>>>
|
||||||
|
: std::true_type {};
|
||||||
|
|
||||||
|
/// \brief Utility template for verifying elems header type.
|
||||||
|
template <typename T>
|
||||||
|
using verify_elems_header = std::enable_if_t<is_elems_header<T>::value, bool>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Calculate the corresponding queue position modulo the index value.
|
* \brief Calculate the corresponding queue position modulo the index value.
|
||||||
@ -128,7 +135,7 @@ using is_elems_header = decltype(
|
|||||||
* \param idx a elems array index
|
* \param idx a elems array index
|
||||||
* \return index_t - a corresponding queue position
|
* \return index_t - a corresponding queue position
|
||||||
*/
|
*/
|
||||||
template <typename H, is_elems_header<H> = true>
|
template <typename H, verify_elems_header<H> = true>
|
||||||
constexpr index_t trunc_index(H const &hdr, index_t idx) noexcept {
|
constexpr index_t trunc_index(H const &hdr, index_t idx) noexcept {
|
||||||
// `circ_size == 2^N` => `idx & (circ_size - 1)`
|
// `circ_size == 2^N` => `idx & (circ_size - 1)`
|
||||||
return hdr.valid() ? (idx % hdr.circ_size) : 0;
|
return hdr.valid() ? (idx % hdr.circ_size) : 0;
|
||||||
@ -160,8 +167,8 @@ struct producer<trans::unicast, relation::single> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename H, typename C, typename U,
|
template <typename T, typename H, typename C, typename U,
|
||||||
is_elems_header<H> = true,
|
verify_elems_header<H> = true,
|
||||||
is_convertible<H, header_impl> = true>
|
convertible<H, header_impl> = true>
|
||||||
static bool enqueue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &&src) noexcept {
|
static bool enqueue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &&src) noexcept {
|
||||||
auto w_idx = hdr.w_idx;
|
auto w_idx = hdr.w_idx;
|
||||||
auto w_cur = trunc_index(hdr, w_idx);
|
auto w_cur = trunc_index(hdr, w_idx);
|
||||||
@ -191,8 +198,8 @@ struct producer<trans::unicast, relation::multi> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename H, typename C, typename U,
|
template <typename T, typename H, typename C, typename U,
|
||||||
is_elems_header<H> = true,
|
verify_elems_header<H> = true,
|
||||||
is_convertible<H, header_impl> = true>
|
convertible<H, header_impl> = true>
|
||||||
static bool enqueue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &&src) noexcept {
|
static bool enqueue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &&src) noexcept {
|
||||||
auto w_idx = hdr.w_idx.load(std::memory_order_acquire);
|
auto w_idx = hdr.w_idx.load(std::memory_order_acquire);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -226,8 +233,8 @@ struct consumer<trans::unicast, relation::single> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename H, typename C, typename U,
|
template <typename T, typename H, typename C, typename U,
|
||||||
is_elems_header<H> = true,
|
verify_elems_header<H> = true,
|
||||||
is_convertible<H, header_impl> = true,
|
convertible<H, header_impl> = true,
|
||||||
std::enable_if_t<std::is_nothrow_move_assignable<U>::value, bool> = true>
|
std::enable_if_t<std::is_nothrow_move_assignable<U>::value, bool> = true>
|
||||||
static bool dequeue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &des) noexcept {
|
static bool dequeue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &des) noexcept {
|
||||||
auto r_idx = hdr.r_idx;
|
auto r_idx = hdr.r_idx;
|
||||||
@ -257,8 +264,8 @@ struct consumer<trans::unicast, relation::multi> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename H, typename C, typename U,
|
template <typename T, typename H, typename C, typename U,
|
||||||
is_elems_header<H> = true,
|
verify_elems_header<H> = true,
|
||||||
is_convertible<H, header_impl> = true,
|
convertible<H, header_impl> = true,
|
||||||
std::enable_if_t<std::is_nothrow_move_assignable<U>::value, bool> = true>
|
std::enable_if_t<std::is_nothrow_move_assignable<U>::value, bool> = true>
|
||||||
static bool dequeue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &des) noexcept {
|
static bool dequeue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &des) noexcept {
|
||||||
auto r_idx = hdr.r_idx.load(std::memory_order_acquire);
|
auto r_idx = hdr.r_idx.load(std::memory_order_acquire);
|
||||||
@ -303,8 +310,8 @@ struct producer<trans::broadcast, relation::single> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename H, typename C, typename U,
|
template <typename T, typename H, typename C, typename U,
|
||||||
is_elems_header<H> = true,
|
verify_elems_header<H> = true,
|
||||||
is_convertible<H, header_impl> = true>
|
convertible<H, header_impl> = true>
|
||||||
static bool enqueue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &&src) noexcept {
|
static bool enqueue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &&src) noexcept {
|
||||||
auto w_idx = hdr.w_idx.load(std::memory_order_acquire);
|
auto w_idx = hdr.w_idx.load(std::memory_order_acquire);
|
||||||
auto w_beg = hdr.w_beg.load(std::memory_order_relaxed);
|
auto w_beg = hdr.w_beg.load(std::memory_order_relaxed);
|
||||||
@ -341,8 +348,8 @@ struct producer<trans::broadcast, relation::multi> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename H, typename C, typename U,
|
template <typename T, typename H, typename C, typename U,
|
||||||
is_elems_header<H> = true,
|
verify_elems_header<H> = true,
|
||||||
is_convertible<H, header_impl> = true>
|
convertible<H, header_impl> = true>
|
||||||
static bool enqueue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &&src) noexcept {
|
static bool enqueue(::LIBIMP::span<element<T>> elems, H &hdr, C &/*ctx*/, U &&src) noexcept {
|
||||||
auto w_flags = hdr.w_flags.load(std::memory_order_acquire);
|
auto w_flags = hdr.w_flags.load(std::memory_order_acquire);
|
||||||
index_t w_idx;
|
index_t w_idx;
|
||||||
@ -377,13 +384,11 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr static index_t get_begin(state::flag_t flags) noexcept {
|
constexpr static index_t get_begin(state::flag_t flags) noexcept {
|
||||||
constexpr auto index_bits = sizeof(index_t) * CHAR_BIT;
|
return index_t(flags >> (sizeof(index_t) * CHAR_BIT));
|
||||||
return index_t(flags >> index_bits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr static state::flag_t make_flags(index_t idx, index_t beg) noexcept {
|
constexpr static state::flag_t make_flags(index_t idx, index_t beg) noexcept {
|
||||||
constexpr auto index_bits = sizeof(index_t) * CHAR_BIT;
|
return state::flag_t(idx) | (state::flag_t(beg) << (sizeof(index_t) * CHAR_BIT));
|
||||||
return state::flag_t(idx) | (state::flag_t(beg) << index_bits);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -398,8 +403,8 @@ struct consumer<trans::broadcast, relation::multi> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename H, typename C, typename U,
|
template <typename T, typename H, typename C, typename U,
|
||||||
is_elems_header<H> = true,
|
verify_elems_header<H> = true,
|
||||||
is_convertible<C, context_impl> = true,
|
convertible<C, context_impl> = true,
|
||||||
std::enable_if_t<std::is_nothrow_copy_assignable<U>::value, bool> = true>
|
std::enable_if_t<std::is_nothrow_copy_assignable<U>::value, bool> = true>
|
||||||
static bool dequeue(::LIBIMP::span<element<T>> elems, H &hdr, C &ctx, U &des) noexcept {
|
static bool dequeue(::LIBIMP::span<element<T>> elems, H &hdr, C &ctx, U &des) noexcept {
|
||||||
index_t w_idx, w_beg;
|
index_t w_idx, w_beg;
|
||||||
|
|||||||
@ -232,7 +232,7 @@ void test_broadcast(std::size_t np, std::size_t nc) {
|
|||||||
typename concur::traits<PC>::header hdr {imp::make_span(circ)};
|
typename concur::traits<PC>::header hdr {imp::make_span(circ)};
|
||||||
ASSERT_TRUE(hdr.valid());
|
ASSERT_TRUE(hdr.valid());
|
||||||
|
|
||||||
constexpr static std::uint32_t loop_size = 100'0000;
|
constexpr static std::uint32_t loop_size = 10'0000;
|
||||||
|
|
||||||
std::atomic<std::uint64_t> sum {0};
|
std::atomic<std::uint64_t> sum {0};
|
||||||
std::atomic<std::size_t> running {np};
|
std::atomic<std::size_t> running {np};
|
||||||
@ -272,12 +272,12 @@ void test_broadcast(std::size_t np, std::size_t nc) {
|
|||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
// The v.i variable always increases.
|
// The v.i variable always increases.
|
||||||
if (last_i[v.n] >= v.i) {
|
if (last_i[(std::size_t)v.n] >= v.i) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
last_i[v.n] = v.i;
|
last_i[(std::size_t)v.n] = v.i;
|
||||||
sum += v.i;
|
sum += v.i;
|
||||||
++counters[v.n];
|
++counters[(std::size_t)v.n];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user