// // message.h // cli // // Created by Sam Jaffe on 10/10/20. // Copyright © 2020 Sam Jaffe. All rights reserved. // #pragma once #include #include #include namespace cli { namespace detail { template void print(std::ostream &os, T const & tup, std::index_sequence) { os << std::boolalpha; using swallow = int[]; (void)swallow{0, ((void)(os << std::get(tup)), 0)...}; os << std::noboolalpha; } template struct up_string { using type = std::remove_reference_t; }; template struct up_string { using type = std::string; }; template using up_string_t = typename up_string::type; }} namespace cli { struct message { virtual ~message() = default; virtual void print(std::ostream &) const = 0; }; template struct message_impl : public message { std::tuple tuple; message_impl(std::tuple &&tuple) : tuple(std::move(tuple)) {} void print(std::ostream &os) const override { detail::print(os, tuple, std::make_index_sequence{}); } }; template auto make_message(Args &&...args) { using detail::up_string_t; using message_t = message_impl...>; auto tuple = std::make_tuple(std::forward>(args)...); return std::make_shared(std::move(tuple)); } }