Register procedures

For a procedure to be available to run, it needs to have
a call to a REGISTER_PROCEDURE macro.  This macro wraps
a call to a Register class that adds the procedure to the list
along with the name to call it.

Change-Id: I20d02e8f004c1c726228469465ae89b60ee52d66
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/registration.hpp b/registration.hpp
new file mode 100644
index 0000000..d0dde00
--- /dev/null
+++ b/registration.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include <functional>
+#include <map>
+#include <string>
+#include <iostream>
+
+namespace openpower
+{
+namespace util
+{
+
+using ProcedureName = std::string;
+using ProcedureFunction = std::function<void()>;
+using ProcedureMap = std::map<ProcedureName, ProcedureFunction>;
+
+/**
+ * This macro can be used in each procedure cpp file to make it
+ * available to the openpower-proc-control executable.
+ */
+#define REGISTER_PROCEDURE(name, func) \
+  namespace func##_ns \
+  { \
+    openpower::util::Registration r{ \
+        std::move(name), std::move(func)}; \
+  }
+
+
+/**
+ * Used to register procedures.  Each procedure function can then
+ * be found in a map via its name.
+ */
+class Registration
+{
+    public:
+
+        /**
+         *  Adds the procedure name and function to the internal
+         *  procedure map.
+         *
+         *  @param[in] name - the procedure name
+         *  @param[in] function - the function to run
+         */
+        Registration(ProcedureName&& name,
+                     ProcedureFunction&& function)
+        {
+            procedures.emplace(std::move(name), std::move(function));
+        }
+
+        /**
+         * Returns the map of procedures
+         */
+        static const ProcedureMap& getProcedures()
+        {
+            return procedures;
+        }
+
+    private:
+
+        static ProcedureMap procedures;
+};
+
+}
+}