Return sensor object state data as optional

Previously, the getObject function moved the sensor data passed in as a
constant reference, which should not have been done. The intention of
the getObject function is to retrieve the sensor's object state data.
Then, the necessary sensor data and the created object state data can be
appropriately handled for monitoring.

This change is to remove this confusion and clearly create the sensor's
object state data without modifying the sensor set data passed in to
getObject.

Tested:
    Sensor objects are still created correctly
    Sensor states are monitoring and updated as before

Change-Id: I19fc22fa79094d749e7d5f3b2693094e245b5a4a
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/mainloop.cpp b/mainloop.cpp
index 5324fcd..c18ae7f 100644
--- a/mainloop.cpp
+++ b/mainloop.cpp
@@ -249,22 +249,23 @@
  * atleast the `Value` interface, otherwise returns without creating the object.
  * If the `Value` interface is successfully created, by reading the sensor's
  * corresponding sysfs file's value, the additional interfaces for the sensor
- * are created and the InterfacesAdded signal is emitted. The sensor is then
- * moved to the list for sensor state monitoring within the main loop.
+ * are created and the InterfacesAdded signal is emitted. The object's state
+ * data is then returned for sensor state monitoring within the main loop.
  */
-void MainLoop::getObject(SensorSet::container_t::const_reference sensor)
+optional_ns::optional<ObjectStateData> MainLoop::getObject(
+        SensorSet::container_t::const_reference sensor)
 {
     auto properties = getIdentifiers(sensor);
     if (std::get<sensorID>(properties).empty() ||
         std::get<sensorLabel>(properties).empty())
     {
-        return;
+        return {};
     }
 
     hwmon::Attributes attrs;
     if (!hwmon::getAttributes(sensor.first.first, attrs))
     {
-        return;
+        return {};
     }
 
     // Get list of return codes for removing sensors on device
@@ -318,7 +319,7 @@
                     rmSensors[std::move(sensor.first)] =
                             std::move(sensor.second);
                 }
-                return;
+                return {};
             }
         }
 #endif
@@ -333,7 +334,7 @@
         log<level::INFO>("Logging failing sysfs file",
                 entry("FILE=%s", file.c_str()));
 #ifdef REMOVE_ON_FAIL
-        return; /* skip adding this sensor for now. */
+        return {}; /* skip adding this sensor for now. */
 #else
         exit(EXIT_FAILURE);
 #endif
@@ -360,12 +361,8 @@
     // and emit InterfacesAdded.
     valueInterface->emit_object_added();
 
-    auto value = std::make_tuple(
-                     std::move(sensor.second),
-                     std::move(std::get<sensorLabel>(properties)),
-                     std::move(info));
-
-    state[std::move(sensor.first)] = std::move(value);
+    return std::make_pair(std::move(std::get<sensorLabel>(properties)),
+                          std::move(info));
 }
 
 MainLoop::MainLoop(
@@ -454,7 +451,19 @@
 
     for (auto& i : *sensors)
     {
-        getObject(i);
+        auto object = getObject(i);
+        if (object)
+        {
+            // Construct the SensorSet value
+            // std::tuple<SensorSet::mapped_type,
+            //            std::string(Sensor Label),
+            //            ObjectInfo>
+            auto value = std::make_tuple(std::move(i.second),
+                                         std::move((*object).first),
+                                         std::move((*object).second));
+
+            state[std::move(i.first)] = std::move(value);
+        }
     }
 
     /* If there are no sensors specified by labels, exit. */
@@ -607,9 +616,19 @@
         {
             SensorSet::container_t::value_type ssValueType =
                     std::make_pair(it->first, it->second);
-            getObject(ssValueType);
-            if (state.find(it->first) != state.end())
+            auto object = getObject(ssValueType);
+            if (object)
             {
+                // Construct the SensorSet value
+                // std::tuple<SensorSet::mapped_type,
+                //            std::string(Sensor Label),
+                //            ObjectInfo>
+                auto value = std::make_tuple(std::move(ssValueType.second),
+                                             std::move((*object).first),
+                                             std::move((*object).second));
+
+                state[std::move(ssValueType.first)] = std::move(value);
+
                 // Sensor object added, erase entry from removal list
                 auto file = sysfs::make_sysfs_path(
                         ioAccess.path(),
diff --git a/mainloop.hpp b/mainloop.hpp
index d139593..3fbc059 100644
--- a/mainloop.hpp
+++ b/mainloop.hpp
@@ -3,6 +3,7 @@
 #include <string>
 #include <vector>
 #include <experimental/any>
+#include <experimental/optional>
 #include <memory>
 #include <sdbusplus/server.hpp>
 #include "hwmonio.hpp"
@@ -16,11 +17,14 @@
 using Object = std::map<InterfaceType, std::experimental::any>;
 using ObjectInfo = std::tuple<sdbusplus::bus::bus*, std::string, Object>;
 using RetryIO = std::tuple<size_t, std::chrono::milliseconds>;
+using ObjectStateData = std::pair<std::string, ObjectInfo>;
 
 static constexpr auto sensorID = 0;
 static constexpr auto sensorLabel = 1;
 using SensorIdentifiers = std::tuple<std::string, std::string>;
 
+namespace optional_ns = std::experimental;
+
 /** @class MainLoop
  *  @brief hwmon-readd main application loop.
  */
@@ -127,6 +131,10 @@
          * @brief Used to create and add sensor objects
          *
          * @param[in] sensor - Sensor to create/add object for
+         *
+         * @return - Optional
+         *     Object state data on success, nothing on failure
          */
-        void getObject(SensorSet::container_t::const_reference sensor);
+        optional_ns::optional<ObjectStateData> getObject(
+                SensorSet::container_t::const_reference sensor);
 };