message: tweak how we invoke commandstream's commands
  this is to allow the use of C++17 std::invoke
  don't std::move() each argument of the tuple<> instead
  std::move() the tuple itself and perfectly-forward each argument.
  handle return values
  handle synchronous commands
diff: @@ -111,14 +111,21 @@ private:
  // ------------------------------------------------------------------------------------------------
  +template<typename T, typename Type, typename D, typename ... ARGS>
  +constexpr decltype(auto) invoke(Type T::* m, D&& d, ARGS&& ... args) {
  + static_assert(std::is_base_of<T, std::decay_t<D>>::value,
  + "member function and object not related");
  + return (std::forward<D>(d).*m)(std::forward<ARGS>(args)...);
  +}
  +
  template<typename M, typename D, typename T, std::size_t... I>
  -constexpr void trampoline(M&& m, D&& d, T&& t, std::index_sequence<I...>) {
  - (d.*m)(std::move(std::get<I>(std::forward<T>(t)))...);
  +constexpr decltype(auto) trampoline(M&& m, D&& d, T&& t, std::index_sequence<I...>) {
  + return invoke(std::forward<M>(m), std::forward<D>(d), std::get<I>(std::forward<T>(t))...);
  }
  template<typename M, typename D, typename T>
  -constexpr void apply(M&& m, D&& d, T&& t) {
  - trampoline(std::forward<M>(m), std::forward<D>(d), std::forward<T>(t),
  +constexpr decltype(auto) apply(M&& m, D&& d, T&& t) {
  + return trampoline(std::forward<M>(m), std::forward<D>(d), std::forward<T>(t),
  std::make_index_sequence< std::tuple_size<std::remove_reference_t<T>>::value >{});
  }
  @@ -158,7 +165,7 @@ struct CommandType<void (Driver::*)(ARGS...)> {
  // must call this before invoking the method
  self->log();
  #endif
  - apply(std::forward<M>(method), std::forward<D>(driver), self->mArgs);
  + apply(std::forward<M>(method), std::forward<D>(driver), std::move(self->mArgs));
  self->~Command();
  }
  @@ -227,7 +234,7 @@ public:
  #define DECL_DRIVER_API_SYNCHRONOUS(RetType, methodName, paramsDecl, params) \
  inline RetType methodName(paramsDecl) { \
  DEBUG_COMMAND(methodName, params); \
  - return mDriver->methodName(params); \
  + return apply(&Driver::methodName, *mDriver, std::forward_as_tuple(params)); \
  }
  #define DECL_DRIVER_API_RETURN(RetType, methodName, paramsDecl, params) \
  