/* * Copyright (C) 2015-present ScyllaDB */ /* * SPDX-License-Identifier: AGPL-3.0-or-later */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include "seastarx.hh" #include namespace utils { template std::ostream& format_range(std::ostream& os, const Range& items, std::string_view paren = "{}") { fmt::print(os, "{}{}{}", paren.front(), fmt::join(items, ", "), paren.back()); return os; } namespace internal { template struct print_with_comma { const Printable& v; }; template std::ostream& operator<<(std::ostream& os, const print_with_comma& x) { os << x.v; if (NeedsComma) { os << ", "; } return os; } } // namespace internal } // namespace utils namespace std { template std::ostream& operator<<(std::ostream& os, const std::pair& p) { os << "{" << p.first << ", " << p.second << "}"; return os; } template std::ostream& print_tuple(std::ostream& os, const std::tuple& p, std::index_sequence) { return ((os << "{" ) << ... << utils::internal::print_with_comma{std::get(p)}) << "}"; } template std::ostream& operator<<(std::ostream& os, const std::tuple& p) { return print_tuple(os, p, std::make_index_sequence()); } // Vector-like ranges template requires ( std::same_as>> || std::same_as>> || std::same_as>> || std::same_as>> ) std::ostream& operator<<(std::ostream& os, const Range& items) { return utils::format_range(os, items); } template std::ostream& operator<<(std::ostream& os, const std::set& items) { return utils::format_range(os, items); } template std::ostream& operator<<(std::ostream& os, const std::unordered_set& items) { return utils::format_range(os, items); } template std::ostream& operator<<(std::ostream& os, const std::map& items) { return utils::format_range(os, items); } template std::ostream& operator<<(std::ostream& os, const boost::transformed_range& items) { return utils::format_range(os, items); } template std::ostream& operator<<(std::ostream& os, const std::array& items) { return utils::format_range(os, items, "[]"); } template std::ostream& operator<<(std::ostream& os, const std::optional& opt) { if (opt) { os << "{" << *opt << "}"; } else { os << "{}"; } return os; } std::ostream& operator<<(std::ostream& os, const std::strong_ordering& order); std::ostream& operator<<(std::ostream& os, const std::weak_ordering& order); std::ostream& operator<<(std::ostream& os, const std::partial_ordering& order); } // namespace std template struct fmt::formatter> : fmt::formatter { template auto format(const std::optional& opt, FormatContext& ctx) const { if (opt) { return fmt::format_to(ctx.out(), "{}", *opt); } else { return fmt::format_to(ctx.out(), "{{}}"); } } };