replace tuple-based singleton with individual singletons

The tuple-based singletons did not actually enforce singleton behavior
and the requirement of the accessor mechanism to include all of the
member types at once was starting to cause a header prerequisite
tangle. This removes the cross-dependencies and enforces actual
singletons by making a single way to access the class.

Tested: Run ipmitool to show that behavior has not changed

Change-Id: Ie966e1142363d279365b1095066380c8383e9f9b
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/sessions_manager.hpp b/sessions_manager.hpp
index f1d060e..14027db 100644
--- a/sessions_manager.hpp
+++ b/sessions_manager.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "main.hpp"
 #include "session.hpp"
 
 #include <boost/asio/steady_timer.hpp>
@@ -32,12 +33,17 @@
 
 class Manager
 {
+  private:
+    struct Private
+    {
+    };
+
   public:
     // BMC Session ID is the key for the map
     using SessionMap = std::map<SessionID, std::shared_ptr<Session>>;
 
     Manager() = delete;
-    explicit Manager(std::shared_ptr<boost::asio::io_context>& io) :
+    Manager(std::shared_ptr<boost::asio::io_context>& io, const Private&) :
         io(io), timer(*io){};
     ~Manager() = default;
     Manager(const Manager&) = delete;
@@ -46,6 +52,26 @@
     Manager& operator=(Manager&&) = default;
 
     /**
+     * @brief Get a reference to the singleton Manager
+     *
+     * @return Manager reference
+     */
+    static Manager& get()
+    {
+        static std::shared_ptr<Manager> ptr = nullptr;
+        if (!ptr)
+        {
+            std::shared_ptr<boost::asio::io_context> io = getIo();
+            ptr = std::make_shared<Manager>(io, Private());
+            if (!ptr)
+            {
+                throw std::runtime_error("failed to create session manager");
+            }
+        }
+        return *ptr;
+    }
+
+    /**
      * @brief Start an IPMI session
      *
      * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned