6 #ifndef XENIUM_POINTER_QUEUE_TRAITS_HPP
7 #define XENIUM_POINTER_QUEUE_TRAITS_HPP
11 #include <type_traits>
13 namespace xenium::detail {
15 template <
class T,
class... Policies>
16 struct trivially_copyable_pointer_queue_traits {
17 static_assert(std::is_trivially_copyable<T>::value &&
sizeof(T) <
sizeof(
void*));
19 using raw_type =
void**;
20 static raw_type get_raw(value_type& val) {
21 raw_type result =
nullptr;
24 std::memcpy(&result,
static_cast<void*
>(&val),
sizeof(value_type));
27 static void release(value_type&) {}
28 static void store(value_type& target, raw_type val) {
31 std::memcpy(
static_cast<void*
>(&target), &val,
sizeof(value_type));
33 static void delete_value(raw_type) {}
37 template <
class T,
class... Policies>
38 struct pointer_queue_traits {
39 static_assert(std::is_pointer<T>::value,
"T must be a raw pointer type or a std::unique_ptr");
42 template <
class T,
class... Policies>
43 struct pointer_queue_traits<T*, Policies...> {
44 using value_type = T*;
46 static raw_type get_raw(T* val) {
return val; }
47 static void release(value_type) {}
48 static void store(value_type& target, raw_type val) { target = val; }
49 static void delete_value(raw_type) {}
52 template <
class T,
class... Policies>
53 struct pointer_queue_traits<std::unique_ptr<T>, Policies...> {
54 using value_type = std::unique_ptr<T>;
56 static raw_type get_raw(value_type& val) {
return val.get(); }
57 static void release(value_type& val) { (void)val.release(); }
58 static void store(value_type& target, raw_type val) { target.reset(val); }
59 static void delete_value(raw_type v) { std::unique_ptr<T> dummy{v}; }
62 template <
class T,
class... Policies>
63 using pointer_queue_traits_t = std::conditional_t<std::is_trivially_copyable<T>::value &&
sizeof(T) <
sizeof(
void*),
64 trivially_copyable_pointer_queue_traits<T, Policies...>,
65 pointer_queue_traits<T, Policies...>>;