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 #include <type_traits>
12 
13 namespace xenium::detail {
14 
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*));
18  using value_type = T;
19  using raw_type = void**;
20  static raw_type get_raw(value_type& val) {
21  raw_type result = nullptr;
22  // TODO - handle endianess correctly
23  // need to cast to void* to avoid gcc error about "copying an object of non-trivial type"
24  std::memcpy(&result, static_cast<void*>(&val), sizeof(value_type));
25  return result;
26  }
27  static void release(value_type&) {}
28  static void store(value_type& target, raw_type val) {
29  // TODO - handle endianess correctly
30  // need to cast to void* to avoid gcc error about "copying an object of non-trivial type"
31  std::memcpy(static_cast<void*>(&target), &val, sizeof(value_type));
32  }
33  static void delete_value(raw_type) {}
34 };
35 
36 // TODO - specialization for trivially copyable types smaller than void*
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");
40 };
41 
42 template <class T, class... Policies>
43 struct pointer_queue_traits<T*, Policies...> {
44  using value_type = T*;
45  using raw_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) {}
50 };
51 
52 template <class T, class... Policies>
53 struct pointer_queue_traits<std::unique_ptr<T>, Policies...> {
54  using value_type = std::unique_ptr<T>;
55  using raw_type = 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}; }
60 };
61 
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...>>;
66 } // namespace xenium::detail
67 #endif