Add support for returning optional values

Some commands have optional return values. This allows the handlers to
be defined as returning an optional<T> value and then in the body of the
handler set the value in the optional or not.

Tested-by: unit test runs successfully

Change-Id: Ib38a4589609fb1eb192106e511c9ee3a507ac42f
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/test/message/pack.cpp b/test/message/pack.cpp
index b3957cc..03846c5 100644
--- a/test/message/pack.cpp
+++ b/test/message/pack.cpp
@@ -222,6 +222,32 @@
     ASSERT_EQ(p.raw, k);
 }
 
+TEST(PackBasics, OptionalEmpty)
+{
+    // an optional will only pack if the value is present
+    ipmi::message::Payload p;
+    std::optional<uint32_t> v;
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), 0);
+    // check that the bytes were correctly packed (in byte order)
+    std::vector<uint8_t> k = {};
+    ASSERT_EQ(p.raw, k);
+}
+
+TEST(PackBasics, OptionalContainsValue)
+{
+    // an optional will only pack if the value is present
+    ipmi::message::Payload p;
+    std::optional<uint32_t> v(0x04860002);
+    p.pack(v);
+    // check that the number of bytes matches
+    ASSERT_EQ(p.size(), sizeof(uint32_t));
+    // check that the bytes were correctly packed (in byte order)
+    std::vector<uint8_t> k = {0x02, 0x00, 0x86, 0x04};
+    ASSERT_EQ(p.raw, k);
+}
+
 TEST(PackAdvanced, Uints)
 {
     // all elements will be processed in order, with each multi-byte