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