From 4a63374d9ee3d2412f2337cf34ca55c7315239e3 Mon Sep 17 00:00:00 2001
From: akuesters <42005107+akuesters@users.noreply.github.com>
Date: Thu, 25 Apr 2019 15:22:36 +0200
Subject: [PATCH] Prepare arb::util::optional to be used for automatic
 conversion from/to pybind11::object (#738)

* Add value_type and emplace method to the optional class to support automatic conversion of arb::util::optional in python.
* Add unit test for arb::util::optional::emplace.
---
 arbor/include/arbor/util/optional.hpp | 10 ++++++++++
 test/unit/test_optional.cpp           | 15 +++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/arbor/include/arbor/util/optional.hpp b/arbor/include/arbor/util/optional.hpp
index f36d3b39..e15d5add 100644
--- a/arbor/include/arbor/util/optional.hpp
+++ b/arbor/include/arbor/util/optional.hpp
@@ -107,6 +107,7 @@ namespace detail {
         using const_rvalue_reference = typename data_type::const_rvalue_reference;
 
     public:
+        using value_type = X;
         using reference = typename data_type::reference;
         using const_reference = typename data_type::const_reference;
         using pointer = typename data_type::pointer;
@@ -165,6 +166,15 @@ namespace detail {
             }
             set = false;
         }
+
+        template <typename Y>
+        void emplace(Y&& y) {
+            if (set) {
+                data.destruct();
+            }
+            data.construct(std::forward<Y>(y));
+            set = true;
+        }
     };
 
     // type utilities
diff --git a/test/unit/test_optional.cpp b/test/unit/test_optional.cpp
index c14b34de..760e4a68 100644
--- a/test/unit/test_optional.cpp
+++ b/test/unit/test_optional.cpp
@@ -287,3 +287,18 @@ TEST(optional, just) {
     EXPECT_EQ(3, o2.value());
     EXPECT_EQ(4, o3.value());
 }
+
+TEST(optional, emplace) {
+    optional<int> o1(7);
+    optional<std::array<double, 3>> o2{{22., 22., 22.}};
+    int x = 42;
+    std::array<double, 3> arr{{4.5, 7.1, 1.2}};
+
+    o1.emplace(x);
+    o2.emplace(arr);
+
+    EXPECT_EQ(42, o1.value());
+    EXPECT_EQ(4.5, o2.value()[0]);
+    EXPECT_EQ(7.1, o2.value()[1]);
+    EXPECT_EQ(1.2, o2.value()[2]);
+}
-- 
GitLab