Remove grouping for append

These APIs are fairly complex.  Similar to what was done for the
read_single class of values, simplify these using c++17 template
expressions.

Tested: Booted gb200nvl-bmc.  Services launched, no new crashes seen.

Change-Id: If2604113efa578062890f11d18ecca7a9f249e9c
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/include/sdbusplus/message/append.hpp b/include/sdbusplus/message/append.hpp
index a34d7ef..31dad9f 100644
--- a/include/sdbusplus/message/append.hpp
+++ b/include/sdbusplus/message/append.hpp
@@ -45,60 +45,6 @@
 namespace details
 {
 
-/** @brief Utility to identify C++ types that may not be grouped into a
- *         single sd_bus_message_append call and instead need special
- *         handling.
- *
- *  @tparam T - Type for identification.
- *
- *  User-defined types are expected to inherit from std::false_type.
- *  Enums are converted to strings, so must be done one at a time.
- */
-template <typename T, typename Enable = void>
-struct can_append_multiple :
-    std::conditional_t<std::is_enum_v<T>, std::false_type, std::true_type>
-{};
-// unix_fd's int needs to be wrapped.
-template <>
-struct can_append_multiple<unix_fd> : std::false_type
-{};
-// std::string needs a c_str() call.
-template <>
-struct can_append_multiple<std::string> : std::false_type
-{};
-// object_path needs a c_str() call.
-template <>
-struct can_append_multiple<object_path> : std::false_type
-{};
-// signature needs a c_str() call.
-template <>
-struct can_append_multiple<signature> : std::false_type
-{};
-// bool needs to be resized to int, per sdbus documentation.
-template <>
-struct can_append_multiple<bool> : std::false_type
-{};
-// std::vector/map/unordered_map/set need loops
-template <utility::is_dbus_array T>
-struct can_append_multiple<T> : std::false_type
-{};
-// std::pair needs to be broken down into components.
-template <typename T1, typename T2>
-struct can_append_multiple<std::pair<T1, T2>> : std::false_type
-{};
-// std::tuple needs to be broken down into components.
-template <typename... Args>
-struct can_append_multiple<std::tuple<Args...>> : std::false_type
-{};
-// variant needs to be broken down into components.
-template <typename... Args>
-struct can_append_multiple<std::variant<Args...>> : std::false_type
-{};
-
-template <typename... Args>
-inline constexpr bool can_append_multiple_v =
-    can_append_multiple<Args...>::value;
-
 /** @brief Utility to append a single C++ element into a sd_bus_message.
  *
  *  User-defined types are expected to specialize this template in order to
@@ -376,193 +322,12 @@
         std::visit(apply, s);
     }
 };
-
-template <typename T>
-void tuple_item_append(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                       T&& t)
-{
-    sdbusplus::message::append(intf, m, t);
-}
-
-template <int Index>
-struct AppendHelper
-{
-    template <typename... Fields>
-    static void op(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                   std::tuple<Fields...> field_tuple)
-    {
-        auto field = std::get<Index - 1>(field_tuple);
-
-        AppendHelper<Index - 1>::op(intf, m, std::move(field_tuple));
-
-        tuple_item_append(intf, m, field);
-    }
-};
-
-template <>
-struct AppendHelper<1>
-{
-    template <typename... Fields>
-    static void op(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                   std::tuple<Fields...> field_tuple)
-    {
-        tuple_item_append(intf, m, std::get<0>(field_tuple));
-    }
-};
-
-/** @brief Append a tuple of 2 or more entries into the sd_bus_message.
- *
- *  @tparam Tuple - The tuple type to append.
- *  @param[in] t - The tuple to append.
- *
- *  A tuple of 2 or more entries can be added as a set with
- *  sd_bus_message_append.
- */
-template <typename Tuple>
-std::enable_if_t<2 <= std::tuple_size_v<Tuple>> append_tuple(
-    sdbusplus::SdBusInterface* intf, sd_bus_message* m, Tuple&& t)
-{
-    // This was called because the tuple had at least 2 items in it.
-    AppendHelper<std::tuple_size_v<Tuple>>::op(intf, m, std::move(t));
-}
-
-/** @brief Append a tuple of exactly 1 entry into the sd_bus_message.
- *
- *  @tparam Tuple - The tuple type to append.
- *  @param[in] t - The tuple to append.
- *
- *  A tuple of 1 entry can be added with sd_bus_message_append_basic.
- *
- *  Note: Some 1-entry tuples may need special handling due to
- *  can_append_multiple_v == false.
- */
-template <typename Tuple>
-std::enable_if_t<1 == std::tuple_size_v<Tuple>> append_tuple(
-    sdbusplus::SdBusInterface* intf, sd_bus_message* m, Tuple&& t)
-{
-    using itemType = decltype(std::get<0>(t));
-    append_single_t<itemType>::op(intf, m,
-                                  std::forward<itemType>(std::get<0>(t)));
-}
-
-/** @brief Append a tuple of 0 entries - no-op.
- *
- *  This a no-op function that is useful due to variadic templates.
- */
-template <typename Tuple>
-std::enable_if_t<0 == std::tuple_size_v<Tuple>> inline append_tuple(
-    sdbusplus::SdBusInterface* /*intf*/, sd_bus_message* /*m*/, Tuple&& /*t*/)
-{}
-
-/** @brief Group a sequence of C++ types for appending into an sd_bus_message.
- *  @tparam Tuple - A tuple of previously analyzed types.
- *  @tparam Arg - The argument to analyze for grouping.
- *
- *  Specialization for when can_append_multiple_v<Arg> is true.
- */
-template <typename Tuple, typename Arg>
-std::enable_if_t<can_append_multiple_v<types::details::type_id_downcast_t<Arg>>>
-    append_grouping(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                    Tuple&& t, Arg&& arg);
-/** @brief Group a sequence of C++ types for appending into an sd_bus_message.
- *  @tparam Tuple - A tuple of previously analyzed types.
- *  @tparam Arg - The argument to analyze for grouping.
- *
- *  Specialization for when can_append_multiple_v<Arg> is false.
- */
-template <typename Tuple, typename Arg>
-std::enable_if_t<
-    !can_append_multiple_v<types::details::type_id_downcast_t<Arg>>>
-    append_grouping(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                    Tuple&& t, Arg&& arg);
-/** @brief Group a sequence of C++ types for appending into an sd_bus_message.
- *  @tparam Tuple - A tuple of previously analyzed types.
- *  @tparam Arg - The argument to analyze for grouping.
- *  @tparam Rest - The remaining arguments left to analyze.
- *
- *  Specialization for when can_append_multiple_v<Arg> is true.
- */
-template <typename Tuple, typename Arg, typename... Rest>
-std::enable_if_t<can_append_multiple_v<types::details::type_id_downcast_t<Arg>>>
-    append_grouping(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                    Tuple&& t, Arg&& arg, Rest&&... rest);
-/** @brief Group a sequence of C++ types for appending into an sd_bus_message.
- *  @tparam Tuple - A tuple of previously analyzed types.
- *  @tparam Arg - The argument to analyze for grouping.
- *  @tparam Rest - The remaining arguments left to analyze.
- *
- *  Specialization for when can_append_multiple_v<Arg> is false.
- */
-template <typename Tuple, typename Arg, typename... Rest>
-std::enable_if_t<
-    !can_append_multiple_v<types::details::type_id_downcast_t<Arg>>>
-    append_grouping(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                    Tuple&& t, Arg&& arg, Rest&&... rest);
-
-template <typename Tuple, typename Arg>
-std::enable_if_t<can_append_multiple_v<types::details::type_id_downcast_t<Arg>>>
-    append_grouping(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                    Tuple&& t, Arg&& arg)
-{
-    // Last element of a sequence and can_append_multiple, so add it to
-    // the tuple and call append_tuple.
-
-    append_tuple(intf, m,
-                 std::tuple_cat(std::forward<Tuple>(t),
-                                std::forward_as_tuple(std::forward<Arg>(arg))));
-}
-
-template <typename Tuple, typename Arg>
-std::enable_if_t<
-    !can_append_multiple_v<types::details::type_id_downcast_t<Arg>>>
-    append_grouping(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                    Tuple&& t, Arg&& arg)
-{
-    // Last element of a sequence but !can_append_multiple, so call
-    // append_tuple on the previous elements and separately this single
-    // element.
-
-    append_tuple(intf, m, std::forward<Tuple>(t));
-    append_tuple(intf, m, std::forward_as_tuple(std::forward<Arg>(arg)));
-}
-
-template <typename Tuple, typename Arg, typename... Rest>
-std::enable_if_t<can_append_multiple_v<types::details::type_id_downcast_t<Arg>>>
-    append_grouping(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                    Tuple&& t, Arg&& arg, Rest&&... rest)
-{
-    // Not the last element of a sequence and can_append_multiple, so add it
-    // to the tuple and keep grouping.
-
-    append_grouping(
-        intf, m,
-        std::tuple_cat(std::forward<Tuple>(t),
-                       std::forward_as_tuple(std::forward<Arg>(arg))),
-        std::forward<Rest>(rest)...);
-}
-
-template <typename Tuple, typename Arg, typename... Rest>
-std::enable_if_t<
-    !can_append_multiple_v<types::details::type_id_downcast_t<Arg>>>
-    append_grouping(sdbusplus::SdBusInterface* intf, sd_bus_message* m,
-                    Tuple&& t, Arg&& arg, Rest&&... rest)
-{
-    // Not the last element of a sequence but !can_append_multiple, so call
-    // append_tuple on the previous elements and separately this single
-    // element and then group the remaining elements.
-
-    append_tuple(intf, m, std::forward<Tuple>(t));
-    append_tuple(intf, m, std::forward_as_tuple(std::forward<Arg>(arg)));
-    append_grouping(intf, m, std::make_tuple(), std::forward<Rest>(rest)...);
-}
-
 } // namespace details
 
 template <typename... Args>
 void append(sdbusplus::SdBusInterface* intf, sd_bus_message* m, Args&&... args)
 {
-    details::append_grouping(intf, m, std::make_tuple(),
-                             std::forward<Args>(args)...);
+    (details::append_single_t<Args>::op(intf, m, args), ...);
 }
 
 } // namespace message
diff --git a/test/message/append.cpp b/test/message/append.cpp
index 8e0e558..bbba074 100644
--- a/test/message/append.cpp
+++ b/test/message/append.cpp
@@ -106,8 +106,6 @@
 
 TEST_F(AppendTest, RValueInt)
 {
-    static_assert(
-        sdbusplus::message::details::can_append_multiple_v<decltype(1)>);
     expect_basic<int>(SD_BUS_TYPE_INT32, 1);
     new_message().append(1);
 }
@@ -115,8 +113,6 @@
 TEST_F(AppendTest, LValueInt)
 {
     const int a = 1;
-    static_assert(
-        sdbusplus::message::details::can_append_multiple_v<decltype(a)>);
     expect_basic<int>(SD_BUS_TYPE_INT32, a);
     new_message().append(a);
 }
@@ -184,8 +180,6 @@
 TEST_F(AppendTest, XValueCString)
 {
     const char* s = "asdf";
-    static_assert(
-        sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
     expect_basic_string(SD_BUS_TYPE_STRING, s);
     new_message().append(std::move(s));
 }
@@ -199,8 +193,6 @@
 TEST_F(AppendTest, LValueString)
 {
     std::string s{"asdf"};
-    static_assert(
-        !sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
     expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
     new_message().append(s);
 }
@@ -261,8 +253,6 @@
 TEST_F(AppendTest, Array)
 {
     const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
-    static_assert(
-        !sdbusplus::message::details::can_append_multiple_v<decltype(a)>);
 
     {
         expect_append_array(SD_BUS_TYPE_DOUBLE, a.size() * sizeof(double));
@@ -274,8 +264,6 @@
 {
     const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
     auto s = std::span{a};
-    static_assert(
-        !sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
 
     {
         expect_append_array(SD_BUS_TYPE_DOUBLE, a.size() * sizeof(double));