Skip to content

Commit ab8b59b

Browse files
committed
Use own class for MovableUniquePtr
1 parent 6946c91 commit ab8b59b

File tree

4 files changed

+43
-24
lines changed

4 files changed

+43
-24
lines changed

include/openPMD/auxiliary/Memory.hpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,13 @@
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

3633
namespace 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

include/openPMD/auxiliary/Memory_internal.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@
2121
#pragma once
2222

2323
#include "openPMD/auxiliary/Memory.hpp"
24-
#include "openPMD/auxiliary/UniquePtr.hpp"
25-
#include <memory>
2624

2725
namespace openPMD::auxiliary
2826
{
2927
// cannot use a unique_ptr inside a std::variant, so we represent it with this
3028
using WriteBufferTypes =
31-
std::variant<WriteBuffer::UniquePtr, WriteBuffer::SharedPtr>;
29+
std::variant<WriteBuffer::MovableUniquePtr, WriteBuffer::SharedPtr>;
3230
} // namespace openPMD::auxiliary

src/IO/ADIOS/ADIOS2File.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
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
}

src/auxiliary/Memory.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff 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

167167
WriteBuffer::WriteBuffer(std::shared_ptr<void const> ptr)
@@ -173,8 +173,7 @@ WriteBuffer::WriteBuffer(std::shared_ptr<void const> ptr)
173173

174174
WriteBuffer::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

180179
WriteBuffer::WriteBuffer(WriteBuffer &&) noexcept = default;
@@ -193,8 +192,8 @@ WriteBuffer const &WriteBuffer::operator=(std::shared_ptr<void const> ptr)
193192

194193
WriteBuffer 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

0 commit comments

Comments
 (0)