File tree Expand file tree Collapse file tree 4 files changed +43
-24
lines changed
include/openPMD/auxiliary Expand file tree Collapse file tree 4 files changed +43
-24
lines changed Original file line number Diff line number Diff line change 2222
2323#include " openPMD/Dataset.hpp"
2424#include " openPMD/Datatype.hpp"
25+ #include " openPMD/Error.hpp"
2526#include " openPMD/auxiliary/UniquePtr.hpp"
2627
2728#include < any>
28- #include < complex>
2929#include < functional>
30- #include < iostream>
3130#include < memory>
32- #include < type_traits>
3331#include < utility>
34- #include < variant>
3532
3633namespace openPMD
3734{
@@ -52,8 +49,41 @@ namespace auxiliary
5249 /*
5350 * Sic. Have to put the unique_ptr behind a shared_ptr because
5451 * std::variant does not want immovable types.
52+ * Use a separate class to avoid mistakes in double dereference.
5553 */
56- using UniquePtr = std::shared_ptr<UniquePtrWithLambda<void >>;
54+ struct MovableUniquePtr
55+ : private std::shared_ptr<UniquePtrWithLambda<void >>
56+ {
57+ private:
58+ using parent_t = std::shared_ptr<UniquePtrWithLambda<void >>;
59+
60+ public:
61+ MovableUniquePtr () = default ;
62+ MovableUniquePtr (UniquePtrWithLambda<void > ptr_in)
63+ : parent_t {std::make_shared<UniquePtrWithLambda<void >>(
64+ std::move (ptr_in))}
65+ {}
66+ auto get () -> void *
67+ {
68+ return (**this ).get ();
69+ }
70+ [[nodiscard]] auto get () const -> void const *
71+ {
72+ return (**this ).get ();
73+ }
74+ [[nodiscard]] auto release () -> UniquePtrWithLambda<void>
75+ {
76+ if (parent_t::use_count () > 1 )
77+ {
78+ throw error::Internal (
79+ " Control flow error: UniquePtr variant of WriteBuffer "
80+ " has been copied." );
81+ }
82+ UniquePtrWithLambda<void > res = std::move (**this );
83+ this ->reset ();
84+ return res;
85+ }
86+ };
5787 using SharedPtr = std::shared_ptr<void const >;
5888 /*
5989 * Use std::any publically since some compilers have trouble with
Original file line number Diff line number Diff line change 2121#pragma once
2222
2323#include " openPMD/auxiliary/Memory.hpp"
24- #include " openPMD/auxiliary/UniquePtr.hpp"
25- #include < memory>
2624
2725namespace openPMD ::auxiliary
2826{
2927// cannot use a unique_ptr inside a std::variant, so we represent it with this
3028using WriteBufferTypes =
31- std::variant<WriteBuffer::UniquePtr , WriteBuffer::SharedPtr>;
29+ std::variant<WriteBuffer::MovableUniquePtr , WriteBuffer::SharedPtr>;
3230} // namespace openPMD::auxiliary
Original file line number Diff line number Diff line change 2626#include " openPMD/IO/AbstractIOHandler.hpp"
2727#include " openPMD/IterationEncoding.hpp"
2828#include " openPMD/auxiliary/Environment.hpp"
29+ #include " openPMD/auxiliary/Memory.hpp"
2930#include " openPMD/auxiliary/Memory_internal.hpp"
3031#include " openPMD/auxiliary/StringManip.hpp"
3132
@@ -115,22 +116,13 @@ void WriteDataset::call(ADIOS2File &ba, detail::BufferedPut &bp)
115116 }
116117 else if constexpr (std::is_same_v<
117118 ptr_type,
118- std::shared_ptr<UniquePtrWithLambda< void >> >)
119+ auxiliary::WriteBuffer::MovableUniquePtr >)
119120 {
120121 BufferedUniquePtrPut bput;
121122 bput.name = std::move (bp.name );
122123 bput.offset = std::move (bp.param .offset );
123124 bput.extent = std::move (bp.param .extent );
124- /*
125- * Note: Moving is required here since it's a unique_ptr.
126- * std::forward<>() would theoretically work, but it
127- * requires the type parameter and we don't have that
128- * inside the lambda.
129- * (ptr_type does not work for this case).
130- */
131- // clang-format off
132- bput.data = std::move (*arg); // NOLINT(bugprone-move-forwarding-reference)
133- // clang-format on
125+ bput.data = arg.release ();
134126 bput.dtype = bp.param .dtype ;
135127 ba.m_uniquePtrPuts .push_back (std::move (bput));
136128 }
Original file line number Diff line number Diff line change @@ -161,7 +161,7 @@ allocatePtr(Datatype dtype, Extent const &e)
161161 return allocatePtr (dtype, numPoints);
162162}
163163
164- WriteBuffer::WriteBuffer () : m_buffer(std::make_any<UniquePtr >())
164+ WriteBuffer::WriteBuffer () : m_buffer(std::make_any<MovableUniquePtr >())
165165{}
166166
167167WriteBuffer::WriteBuffer (std::shared_ptr<void const > ptr)
@@ -173,8 +173,7 @@ WriteBuffer::WriteBuffer(std::shared_ptr<void const> ptr)
173173
174174WriteBuffer::WriteBuffer (UniquePtrWithLambda<void > ptr)
175175 : m_buffer(
176- std::make_any<WriteBufferTypes>(
177- std::make_shared<UniquePtrWithLambda<void >>(std::move(ptr))))
176+ std::make_any<WriteBufferTypes>(MovableUniquePtr(std::move(ptr))))
178177{}
179178
180179WriteBuffer::WriteBuffer (WriteBuffer &&) noexcept = default ;
@@ -193,8 +192,8 @@ WriteBuffer const &WriteBuffer::operator=(std::shared_ptr<void const> ptr)
193192
194193WriteBuffer const &WriteBuffer::operator =(UniquePtrWithLambda<void > ptr)
195194{
196- m_buffer = std::make_any<WriteBufferTypes>(
197- std::make_shared<UniquePtrWithLambda< void >> (std::move (ptr)));
195+ m_buffer =
196+ std::make_any<WriteBufferTypes>( MovableUniquePtr (std::move (ptr)));
198197 return *this ;
199198}
200199
You can’t perform that action at this time.
0 commit comments