From bda4351c365466e57af5e6ea76e24c76c160e834 Mon Sep 17 00:00:00 2001
From: Axel Naumann <Axel.Naumann@cern.ch>
Date: Mon, 9 Oct 2017 12:07:37 +0200
Subject: [PATCH] Make TUniWeak out-streamable without weak_ptr or variant
 support.

Create two members, weak and unique_ptr, as I/O cannot handle variant. So we stream both.
O, and I/O cannot handle weak_ptr, but we really need it, so at least support writing (through THttpServer) by adding a `T*` with the same
value as the weak ptr, and have that streamed. This completely breaks the internal symmetry of TUniWeak, but it should get us started...
---
 core/base/v7/inc/ROOT/TDrawable.hxx | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/core/base/v7/inc/ROOT/TDrawable.hxx b/core/base/v7/inc/ROOT/TDrawable.hxx
index 392a2b217be..7f2e22fa588 100644
--- a/core/base/v7/inc/ROOT/TDrawable.hxx
+++ b/core/base/v7/inc/ROOT/TDrawable.hxx
@@ -52,11 +52,12 @@ namespace Internal {
 
 template <class T>
 class TUniWeakPtr {
-   union {
+   // Needs I/O support for union (or variant, actually) {
       std::unique_ptr<T> fUnique;
-      std::weak_ptr<T> fWeak;
-   };
-   bool fIsWeak; ///< fUnique or fWeak?
+      std::weak_ptr<T> fWeak; //! Cannot save for now :-(
+      T* fWeakForIO = nullptr; // Hack to allow streaming *out* of fWeak (reading is still broken because we don't set fWeak)
+   // };
+   bool fIsWeak = false; ///< fUnique or fWeak?
 
 public:
    /// \class Accessor
@@ -97,22 +98,22 @@ public:
       }
    };
 
-   TUniWeakPtr(const std::shared_ptr<T> &ptr): fWeak(ptr), fIsWeak(true) {}
+   TUniWeakPtr() = default;
+   TUniWeakPtr(const std::shared_ptr<T> &ptr): fWeak(ptr), fWeakForIO(ptr.get()), fIsWeak(true) {}
    TUniWeakPtr(std::unique_ptr<T> &&ptr): fUnique(std::move(ptr)), fIsWeak(false) {}
    TUniWeakPtr(TUniWeakPtr &&rhs): fIsWeak(rhs.fIsWeak)
    {
-      if (fIsWeak) {
-         fWeak.weak_ptr(std::move(rhs.fWeak));
-      } else
-         fWeak.unique_ptr(std::move(rhs.fUnique));
+      if (rhs.fIsWeak) {
+         fWeak = std::move(rhs.fWeak);
+         auto shptr = rhs.fWeak.lock();
+         fWeakForIO = shptr.get();
+      } else {
+         fUnique = std::move(rhs.fUnique);
+      }
    }
 
    ~TUniWeakPtr()
    {
-      if (fIsWeak)
-         fWeak.~weak_ptr();
-      else
-         fUnique.~unique_ptr();
    }
 
    Accessor Get() const { return Accessor(*this); }
-- 
GitLab