From f9ded8a2d9e7dfba200045262b668a4b1e49772c Mon Sep 17 00:00:00 2001
From: AlQuemist <alquemist@Lyriks>
Date: Fri, 22 Oct 2021 17:21:52 +0200
Subject: [PATCH] MultiOption: Use std::variant instead of boost::variant

* C++17's `std::variant` is used instead of `boost::variant`.
* `std::stoi` and `std:stod` are used instead of `boost::lexical_cast`.
* `value_str` method is added to return a string representation of the option's value.
---
 Fit/Test/Unit/MultiOptionTest.cpp |  6 +++---
 Fit/Tools/MultiOption.cpp         | 32 +++++++++++++++++++++----------
 Fit/Tools/MultiOption.h           | 12 +++++++-----
 3 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/Fit/Test/Unit/MultiOptionTest.cpp b/Fit/Test/Unit/MultiOptionTest.cpp
index db4967e4e86..c2461ac2ce4 100644
--- a/Fit/Test/Unit/MultiOptionTest.cpp
+++ b/Fit/Test/Unit/MultiOptionTest.cpp
@@ -11,18 +11,18 @@ TEST_F(MultiOptionTest, Variant)
 
     EXPECT_EQ(0, v1.which());
     //    EXPECT_EQ(1, v1.get<int>());
-    EXPECT_EQ(1, boost::get<int>(v1));
+    EXPECT_EQ(1, std::get<int>(v1));
 
     v1 = 2.0;
     EXPECT_EQ(1, v1.which());
     // EXPECT_EQ(2.0, v1.get<double>());
-    EXPECT_EQ(2.0, boost::get<double>(v1));
+    EXPECT_EQ(2.0, std::get<double>(v1));
 
     const std::string text("xxx");
     v1 = text;
     EXPECT_EQ(2, v1.which());
     //    EXPECT_EQ(text, v1.get<std::string>());
-    EXPECT_EQ(text, boost::get<std::string>(v1));
+    EXPECT_EQ(text, std::get<std::string>(v1));
 }
 
 TEST_F(MultiOptionTest, Construction)
diff --git a/Fit/Tools/MultiOption.cpp b/Fit/Tools/MultiOption.cpp
index d0027c29025..71617944c77 100644
--- a/Fit/Tools/MultiOption.cpp
+++ b/Fit/Tools/MultiOption.cpp
@@ -13,7 +13,7 @@
 //  ************************************************************************************************
 
 #include "Fit/Tools/MultiOption.h"
-#include <boost/lexical_cast.hpp>
+#include <string>
 
 MultiOption::MultiOption(const std::string& name) : m_name(name) {}
 
@@ -43,16 +43,28 @@ MultiOption::variant_t& MultiOption::defaultValue()
 }
 
 //! Sets the value of option from string.
-//! TODO find more elegant way (without if/else and boost::lexical_cast
-
 void MultiOption::setFromString(const std::string& value)
 {
-    if (m_value.which() == 0)
-        m_value = boost::lexical_cast<int>(value);
-
-    else if (m_value.which() == 1)
-        m_value = boost::lexical_cast<double>(value);
-
-    else
+    const std::size_t idx = m_value.index();
+    switch(idx) {
+    case 0:
+        m_value = std::stoi(value);
+    break;
+    case 1:
+        m_value = std::stod(value);
+    break;
+    default:
         m_value = value;
+    }
+}
+
+//! Sets the value of option from string.
+std::string MultiOption::value_str()
+{
+    if (std::holds_alternative<int>(m_value))
+        return std::to_string(std::get<int>(m_value));
+    else if (std::holds_alternative<double>(m_value))
+        return std::to_string(std::get<double>(m_value));
+    else  // std::holds_alternative<std::string>(m_value)
+        return std::get<std::string>(m_value);
 }
diff --git a/Fit/Tools/MultiOption.h b/Fit/Tools/MultiOption.h
index 35b3d45d804..29f430de70d 100644
--- a/Fit/Tools/MultiOption.h
+++ b/Fit/Tools/MultiOption.h
@@ -20,15 +20,14 @@
 #ifndef BORNAGAIN_FIT_TOOLS_MULTIOPTION_H
 #define BORNAGAIN_FIT_TOOLS_MULTIOPTION_H
 
-#include <boost/variant.hpp>
+#include <variant>
 #include <string>
 
 //! Stores a single option for minimization algorithm. Int, double, string values are available.
-//! Relies on boost::variant, will be switched to std::variant in C++-17.
 
 class MultiOption {
 public:
-    using variant_t = boost::variant<int, double, std::string>;
+    using variant_t = std::variant<int, double, std::string>;
 
     explicit MultiOption(const std::string& name = "");
 
@@ -49,6 +48,9 @@ public:
     //! Returns the option's default value (i.e. used during construction)
     template <typename T> T getDefault() const;
 
+    //! Returns a string representation of the option's value
+    std::string value_str();
+
     void setFromString(const std::string& value);
 
 private:
@@ -69,12 +71,12 @@ MultiOption::MultiOption(const std::string& name, const T& t, const std::string&
 
 template <typename T> T MultiOption::get() const
 {
-    return boost::get<T>(m_value);
+    return std::get<T>(m_value);
 }
 
 template <typename T> T MultiOption::getDefault() const
 {
-    return boost::get<T>(m_default_value);
+    return std::get<T>(m_default_value);
 }
 
 #endif // BORNAGAIN_FIT_TOOLS_MULTIOPTION_H
-- 
GitLab