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 
12 namespace xenium { namespace detail {
13 
14 template <class T, class... Policies>
15 struct 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*
35 template <class T, class... Policies>
36 struct 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 
40 template <class T, class... Policies>
41 struct 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 
50 template <class T, class... Policies>
51 struct 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 
60 template <class T, class... Policies>
61 using 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