2222
2323#include " openPMD/Dataset.hpp"
2424#include " openPMD/Datatype.hpp"
25+ #include " openPMD/Error.hpp"
2526#include " openPMD/auxiliary/UniquePtr.hpp"
2627
27- #include < complex >
28+ #include < any >
2829#include < functional>
29- #include < iostream>
3030#include < memory>
31- #include < type_traits>
3231#include < utility>
33- #include < variant>
3432
3533namespace openPMD
3634{
@@ -48,30 +46,58 @@ namespace auxiliary
4846 */
4947 struct WriteBuffer
5048 {
51- using EligibleTypes = std::
52- variant<std::shared_ptr<void const >, UniquePtrWithLambda<void >>;
53- EligibleTypes m_buffer;
49+ /*
50+ * Sic. Have to put the unique_ptr behind a shared_ptr because
51+ * std::variant does not want non-copyable types.
52+ * Use a separate class to avoid mistakes in double dereference.
53+ */
54+ struct CopyableUniquePtr
55+ : private std::shared_ptr<UniquePtrWithLambda<void >>
56+ {
57+ private:
58+ using parent_t = std::shared_ptr<UniquePtrWithLambda<void >>;
5459
55- WriteBuffer ();
60+ public:
61+ CopyableUniquePtr ();
62+ CopyableUniquePtr (UniquePtrWithLambda<void > ptr_in);
63+ auto get () -> void *;
64+ [[nodiscard]] auto get () const -> void const *;
65+ [[nodiscard]] auto release () -> UniquePtrWithLambda<void>;
66+ };
67+ using SharedPtr = std::shared_ptr<void const >;
68+ /*
69+ * Use std::any publically since some compilers have trouble with
70+ * certain uses of std::variant, so hide it from them.
71+ * Look into Memory_internal.hpp for the variant type.
72+ * https://github.com/openPMD/openPMD-api/issues/1720
73+ */
74+ std::any m_buffer;
5675
57- template <typename ... Args>
58- explicit WriteBuffer (Args &&...args)
59- : m_buffer(std::forward<Args>(args)...)
60- {}
76+ WriteBuffer ();
77+ WriteBuffer (std::shared_ptr<void const > ptr);
78+ WriteBuffer (UniquePtrWithLambda<void > ptr);
6179
62- WriteBuffer (WriteBuffer &&) noexcept (
63- noexcept (EligibleTypes(std::declval<EligibleTypes &&>())));
80+ WriteBuffer (WriteBuffer &&) noexcept ;
6481 WriteBuffer (WriteBuffer const &) = delete ;
65- WriteBuffer &operator =(WriteBuffer &&) noexcept (noexcept (
66- std::declval<EligibleTypes &>() =
67- std::declval<EligibleTypes &&>()));
82+ WriteBuffer &operator =(WriteBuffer &&) noexcept ;
6883 WriteBuffer &operator =(WriteBuffer const &) = delete ;
6984
7085 WriteBuffer const &operator =(std::shared_ptr<void const > ptr);
71-
72- WriteBuffer const &operator =(UniquePtrWithLambda<void const > ptr);
86+ WriteBuffer const &operator =(UniquePtrWithLambda<void > ptr);
7387
7488 void const *get () const ;
89+
90+ template <typename variant_t >
91+ auto as_variant () -> variant_t &
92+ {
93+ return *std::any_cast<variant_t >(&m_buffer);
94+ }
95+
96+ template <typename variant_t >
97+ auto as_variant () const -> variant_t const &
98+ {
99+ return *std::any_cast<variant_t >(&m_buffer);
100+ }
75101 };
76102} // namespace auxiliary
77103} // namespace openPMD
0 commit comments