openPMD-api
 
Loading...
Searching...
No Matches
UniquePtr.hpp
1/* Copyright 2024-2025 Franz Poeschel
2 *
3 * This file is part of openPMD-api.
4 *
5 * openPMD-api is free software: you can redistribute it and/or modify
6 * it under the terms of of either the GNU General Public License or
7 * the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * openPMD-api is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License and the GNU Lesser General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * and the GNU Lesser General Public License along with openPMD-api.
19 * If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#pragma once
23
24#include <functional>
25#include <iostream>
26#include <memory>
27#include <type_traits>
28
29namespace openPMD
30{
31
32namespace auxiliary
33{
45 template <typename T>
46 class CustomDelete : public std::function<void(std::remove_extent_t<T> *)>
47 {
48 private:
49 using T_decayed = std::remove_extent_t<T>;
50
51 public:
52 using deleter_type = std::function<void(T_decayed *)>;
53
54 /*
55 * Default constructor: Use std::default_delete<T>.
56 * This ensures correct destruction of arrays by using delete[].
57 */
58 CustomDelete();
59
60 CustomDelete(deleter_type func);
61 };
62} // namespace auxiliary
63
81template <typename T>
82class UniquePtrWithLambda
83 : public std::unique_ptr<
84 T,
85 /* Deleter = */ auxiliary::CustomDelete<T>>
86{
87private:
88 using BasePtr = std::unique_ptr<T, auxiliary::CustomDelete<T>>;
89
90public:
91 using T_decayed = std::remove_extent_t<T>;
92
93 UniquePtrWithLambda();
94
95 UniquePtrWithLambda(UniquePtrWithLambda &&) noexcept;
96 UniquePtrWithLambda &operator=(UniquePtrWithLambda &&) noexcept;
97
98 UniquePtrWithLambda(UniquePtrWithLambda const &) = delete;
99 UniquePtrWithLambda &operator=(UniquePtrWithLambda const &) = delete;
100
110 template <
111 typename bare_unique_ptr,
112 typename SFINAE = std::enable_if_t<
113 std::is_same_v<bare_unique_ptr, std::unique_ptr<T>>>>
114 UniquePtrWithLambda(bare_unique_ptr);
115
123 template <
124 typename Del,
125 typename SFINAE = std::enable_if_t<
126 !std::is_same_v<std::unique_ptr<T, Del>, std::unique_ptr<T>>>>
127 UniquePtrWithLambda(std::unique_ptr<T, Del>);
128
132 UniquePtrWithLambda(T_decayed *);
133
137 UniquePtrWithLambda(T_decayed *, std::function<void(T_decayed *)>);
138
146 template <typename U>
147 UniquePtrWithLambda<U> static_cast_() &&;
148};
149
150template <typename T>
151template <typename Del, typename>
152UniquePtrWithLambda<T>::UniquePtrWithLambda(std::unique_ptr<T, Del> ptr)
153 : BasePtr{ptr.release(), auxiliary::CustomDelete<T>{[&]() {
154 if constexpr (std::is_copy_constructible_v<Del>)
155 {
156 return [deleter = std::move(ptr.get_deleter())](
157 T_decayed *del_ptr) { deleter(del_ptr); };
158 }
159 else
160 {
161 /*
162 * The constructor of std::function requires a copyable
163 * lambda. Since Del is not a copyable type, we cannot
164 * capture it directly, but need to put it into a
165 * shared_ptr to make it copyable.
166 */
167 return [deleter = std::make_shared<Del>(
168 std::move(ptr.get_deleter()))](
169 T_decayed *del_ptr) { (*deleter)(del_ptr); };
170 }
171 }()}}
172{}
173
174template <typename T>
175template <typename U>
176UniquePtrWithLambda<U> UniquePtrWithLambda<T>::static_cast_() &&
177{
178 using other_type = std::remove_extent_t<U>;
179 return UniquePtrWithLambda<U>{
180 static_cast<other_type *>(this->release()),
181 [deleter = std::move(this->get_deleter())](other_type *ptr) {
182 deleter(static_cast<T_decayed *>(ptr));
183 }};
184}
185} // namespace openPMD
UniquePtrWithLambda< U > static_cast_() &&
Like std::static_pointer_cast.
Definition UniquePtr.hpp:176
UniquePtrWithLambda(std::unique_ptr< T, Del >)
Conversion constructor from std::unique_ptr<T> with custom deleter.
Definition UniquePtr.hpp:152
Public definitions of openPMD-api.
Definition Date.cpp:29
@ T
time
Definition UnitDimension.hpp:41