38 #ifndef LIBPMEMOBJ_CPP_DESTROYER_HPP
39 #define LIBPMEMOBJ_CPP_DESTROYER_HPP
42 #include <type_traits>
66 struct if_not_array<T[]>;
71 template <
typename T,
size_t N>
72 struct if_not_array<T[N]>;
84 struct if_size_array<T[]>;
89 template <
typename T,
size_t N>
90 struct if_size_array<T[N]> {
99 template <
typename T,
typename... Args>
101 create(
typename if_not_array<T>::type *ptr, Args &&... args)
103 #if __cpp_lib_is_aggregate
104 if constexpr (std::is_aggregate_v<T>)
105 new (
static_cast<void *
>(ptr)) T{std::forward<Args>(args)...};
107 new (
static_cast<void *
>(ptr)) T(std::forward<Args>(args)...);
109 new (
static_cast<void *
>(ptr)) T(std::forward<Args>(args)...);
116 template <
typename T,
typename... Args>
118 create(
typename if_size_array<T>::type *ptr, Args &&... args)
120 typedef typename detail::pp_array_type<T>::type I;
121 enum { N = pp_array_elems<T>::elems };
123 for (std::size_t i = 0; i < N; ++i)
124 create<I>(&(*ptr)[i], std::forward<Args>(args)...);
132 template <
typename T,
size_t... Indices,
typename Tuple>
134 create_from_tuple(
void *ptr, index_sequence<Indices...>, Tuple tuple)
136 new (ptr) T(std::get<Indices>(std::move(tuple))...);
144 template <
typename T,
typename Tuple,
typename... Args>
146 c_style_construct(
void *ptr,
void *arg)
148 auto *arg_pack =
static_cast<Tuple *
>(arg);
150 typedef typename make_index_sequence<Args...>::type index;
152 create_from_tuple<T>(ptr, index(), std::move(*arg_pack));
163 template <
typename T,
164 typename =
typename std::enable_if<!std::is_pod<T>::value>::type>
166 destroy(
typename if_not_array<T>::type &arg)
174 template <
typename T,
typename dummy = void,
175 typename =
typename std::enable_if<std::is_pod<T>::value>::type>
177 destroy(
typename if_not_array<T>::type &)
184 template <
typename T>
186 destroy(
typename if_size_array<T>::type &arg)
188 typedef typename detail::pp_array_type<T>::type I;
189 enum { N = pp_array_elems<T>::elems };
191 for (std::size_t i = 0; i < N; ++i)
192 destroy<I>(arg[N - 1 - i]);