PMDK C++ bindings  1.11.1
This is the C++ bindings documentation for PMDK's libpmemobj.
life.hpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* Copyright 2016-2020, Intel Corporation */
3 
9 #ifndef LIBPMEMOBJ_CPP_DESTROYER_HPP
10 #define LIBPMEMOBJ_CPP_DESTROYER_HPP
11 
12 #include <cstddef>
13 #include <type_traits>
14 #include <utility>
15 
18 
19 namespace pmem
20 {
21 
22 namespace detail
23 {
24 
25 /*
26  * Template for checking if T is not an array.
27  */
28 template <typename T>
29 struct if_not_array {
30  typedef T type;
31 };
32 
33 /*
34  * Template for checking if T is not an array.
35  */
36 template <typename T>
37 struct if_not_array<T[]>;
38 
39 /*
40  * Template for checking if T is not an array.
41  */
42 template <typename T, size_t N>
43 struct if_not_array<T[N]>;
44 
45 /*
46  * Template for checking if T is an array.
47  */
48 template <typename T>
49 struct if_size_array;
50 
51 /*
52  * Template for checking if T is an array.
53  */
54 template <typename T>
55 struct if_size_array<T[]>;
56 
57 /*
58  * Template for checking if T is an array.
59  */
60 template <typename T, size_t N>
61 struct if_size_array<T[N]> {
62  typedef T type[N];
63 };
64 
65 /*
66  * Calls object's constructor.
67  *
68  * Supports aggregate initialization since C++17
69  */
70 template <typename T, typename... Args>
71 void
72 create(typename if_not_array<T>::type *ptr, Args &&... args)
73 {
74 #if __cpp_lib_is_aggregate
75  if constexpr (std::is_aggregate_v<T>)
76  new (static_cast<void *>(ptr)) T{std::forward<Args>(args)...};
77  else
78  new (static_cast<void *>(ptr)) T(std::forward<Args>(args)...);
79 #else
80  new (static_cast<void *>(ptr)) T(std::forward<Args>(args)...);
81 #endif
82 }
83 
84 /*
85  * Recursively calls array's elements' constructors.
86  */
87 template <typename T, typename... Args>
88 void
89 create(typename if_size_array<T>::type *ptr, Args &&... args)
90 {
91  typedef typename detail::pp_array_type<T>::type I;
92  enum { N = pp_array_elems<T>::elems };
93 
94  for (std::size_t i = 0; i < N; ++i)
95  create<I>(&(*ptr)[i], std::forward<Args>(args)...);
96 }
97 
98 /*
99  * Calls the objects constructor.
100  *
101  * Unpacks the tuple to get constructor's parameters.
102  */
103 template <typename T, size_t... Indices, typename Tuple>
104 void
105 create_from_tuple(void *ptr, index_sequence<Indices...>, Tuple tuple)
106 {
107  new (ptr) T(std::get<Indices>(std::move(tuple))...);
108 }
109 
110 /*
111  * C-style function which calls T constructor with arguments packed in a tuple.
112  *
113  * The arg is a tuple containing constructor parameters.
114  */
115 template <typename T, typename Tuple, typename... Args>
116 int
117 c_style_construct(void *ptr, void *arg)
118 {
119  auto *arg_pack = static_cast<Tuple *>(arg);
120 
121  typedef typename make_index_sequence<Args...>::type index;
122  try {
123  create_from_tuple<T>(ptr, index(), std::move(*arg_pack));
124  } catch (...) {
125  return -1;
126  }
127 
128  return 0;
129 }
130 
131 /*
132  * Calls object's destructor.
133  */
134 template <typename T,
135  typename = typename std::enable_if<
136  !std::is_trivially_destructible<T>::value>::type>
137 void
138 destroy(typename if_not_array<T>::type &arg)
139 {
140  arg.~T();
141 }
142 
143 /*
144  * Don't call destructors for POD types.
145  */
146 template <typename T, typename dummy = void,
147  typename = typename std::enable_if<
148  std::is_trivially_destructible<T>::value>::type>
149 void
150 destroy(typename if_not_array<T>::type &)
151 {
152 }
153 
154 /*
155  * Recursively calls array's elements' destructors.
156  */
157 template <typename T>
158 void
159 destroy(typename if_size_array<T>::type &arg)
160 {
161  typedef typename detail::pp_array_type<T>::type I;
162  enum { N = pp_array_elems<T>::elems };
163 
164  for (std::size_t i = 0; i < N; ++i)
165  destroy<I>(arg[N - 1 - i]);
166 }
167 
168 } /* namespace detail */
169 
170 } /* namespace pmem */
171 
172 #endif /* LIBPMEMOBJ_CPP_DESTROYER_HPP */
pmem
Persistent memory namespace.
Definition: allocation_flag.hpp:15
integer_sequence.hpp
Create c++14 style index sequence.
array_traits.hpp
Common array traits.