xenium
pointer_queue_traits.hpp
1//
2// Copyright (c) 2018-2020 Manuel Pöter.
3// Licensed under the MIT License. See LICENSE file in the project root for full license information.
4//
5
6#ifndef XENIUM_POINTER_QUEUE_TRAITS_HPP
7#define XENIUM_POINTER_QUEUE_TRAITS_HPP
8
9#include <cstring>
10#include <memory>
11
12namespace xenium { namespace detail {
13
14template <class T, class... Policies>
15struct trivially_copyable_pointer_queue_traits {
16 static_assert(std::is_trivially_copyable<T>::value && sizeof(T) < sizeof(void*), "");
17 using value_type = T;
18 using raw_type = void**;
19 static raw_type get_raw(value_type& val) {
20 raw_type result = nullptr;
21 // TODO - handle endianess correctly
22 std::memcpy(&result, &val, sizeof(value_type));
23 return result;
24 }
25 static void release(value_type&) {}
26 static void store(value_type& target, raw_type val) {
27 // TODO - handle endianess correctly
28 std::memcpy(&target, &val, sizeof(value_type));
29 }
30 static void delete_value(raw_type) {}
31};
32
33
34// TODO - specialization for trivially copyable types smaller than void*
35template <class T, class... Policies>
36struct pointer_queue_traits {
37 static_assert(std::is_pointer<T>::value, "T must be a raw pointer type or a std::unique_ptr");
38};
39
40template <class T, class... Policies>
41struct pointer_queue_traits<T*, Policies...> {
42 using value_type = T*;
43 using raw_type = T*;
44 static raw_type get_raw(T* val) { return val; }
45 static void release(value_type) {}
46 static void store(value_type& target, raw_type val) { target = val; }
47 static void delete_value(raw_type) {}
48};
49
50template <class T, class... Policies>
51struct pointer_queue_traits<std::unique_ptr<T>, Policies...> {
52 using value_type = std::unique_ptr<T>;
53 using raw_type = T*;
54 static raw_type get_raw(value_type& val) { return val.get(); }
55 static void release(value_type& val) { val.release(); }
56 static void store(value_type& target, raw_type val) { target.reset(val); }
57 static void delete_value(raw_type v) { std::unique_ptr<T> dummy{v}; }
58};
59
60template <class T, class... Policies>
61using pointer_queue_traits_t = std::conditional_t<
62 std::is_trivially_copyable<T>::value && sizeof(T) < sizeof(void*),
63 trivially_copyable_pointer_queue_traits<T, Policies...>,
64 pointer_queue_traits<T, Policies...>>;
65}}
66#endif