From 71b9344f2995f2930a5d096fa2726f4858ad346e Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Fri, 25 Nov 2022 17:00:11 +0800 Subject: [PATCH] crimson/os: specialize fmt::formatter<> for StagedIterator StagedIterator is a nested class of stage_t, which is in turn a template class. it would be impossible to partial specialize fmt::formatter<> for a nested class of a template class. to workaround this, we specialize fmt::formatter<> for a type which has `do_format_to()` method, and define this method for StagedIterator. since seastar::logger is the only user of the operator<<() operator, the original operator<<() operator is replaced with this new helper method. Signed-off-by: Kefu Chai --- .../os/seastore/object_data_handler.cc | 2 +- .../staged-fltree/stages/stage.h | 33 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/crimson/os/seastore/object_data_handler.cc b/src/crimson/os/seastore/object_data_handler.cc index 5f839ef6fd5e0..f320e424ed93a 100644 --- a/src/crimson/os/seastore/object_data_handler.cc +++ b/src/crimson/os/seastore/object_data_handler.cc @@ -359,7 +359,7 @@ struct overwrite_plan_t { } } }; -} // namespace namespace crimson::os::seastore { +} // namespace crimson::os::seastore { #if FMT_VERSION >= 90000 template<> struct fmt::formatter : fmt::ostream_formatter {}; diff --git a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h index 6ed05d7e1c1df..7185b15eedc40 100644 --- a/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h +++ b/src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h @@ -1669,27 +1669,30 @@ struct staged { } } } - std::ostream& print(std::ostream& os, bool is_top) const { + + template + auto do_format_to(OutputIt out, bool is_top) const { if (valid()) { if (iter->is_end()) { - return os << "END"; + return fmt::format_to(out, "END"); } else { - os << index(); + out = fmt::format_to(out, "{}", index()); } } else { if (is_top) { - return os << "invalid StagedIterator!"; + return fmt::format_to(out, "invalid StagedIterator!"); } else { - os << "0!"; + out = fmt::format_to(out, "0!"); } } if constexpr (!IS_BOTTOM) { - os << ", "; - return this->_nxt.print(os, false); + out = fmt::format_to(out, ", "); + return this->_nxt.do_format_to(out, false); } else { - return os; + return out; } } + position_t get_pos() const { if (valid()) { if constexpr (IS_BOTTOM) { @@ -1727,9 +1730,6 @@ struct staged { } return ret; } - friend std::ostream& operator<<(std::ostream& os, const StagedIterator& iter) { - return iter.print(os, true); - } private: std::optional iter; }; @@ -2475,3 +2475,14 @@ template using node_to_stage_t = typename _node_to_stage_t::type; } + +template +concept HasDoFormatTo = requires(T x, std::back_insert_iterator out) { + { x.do_format_to(out, true) } -> std::same_as; +}; +template struct fmt::formatter : fmt::formatter { + template + auto format(const T& staged_iterator, FormatContext& ctx) { + return staged_iterator.do_format_to(ctx.out(), true); + } +}; -- 2.39.5