]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os: specialize fmt::formatter<> for StagedIterator
authorKefu Chai <tchaikov@gmail.com>
Fri, 25 Nov 2022 09:00:11 +0000 (17:00 +0800)
committerKefu Chai <tchaikov@gmail.com>
Fri, 25 Nov 2022 13:20:58 +0000 (21:20 +0800)
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 <tchaikov@gmail.com>
src/crimson/os/seastore/object_data_handler.cc
src/crimson/os/seastore/onode_manager/staged-fltree/stages/stage.h

index 5f839ef6fd5e0182c4fb8f3fb8ae9a26f893c59b..f320e424ed93addff25fbf6d6cc8ce919c58cd2f 100644 (file)
@@ -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<crimson::os::seastore::overwrite_plan_t> : fmt::ostream_formatter {};
index 6ed05d7e1c1dffd9e5890819c0c92051802bbe9d..7185b15eedc40a4a7f12df8e0627cd09d814c2ca 100644 (file)
@@ -1669,27 +1669,30 @@ struct staged {
         }
       }
     }
-    std::ostream& print(std::ostream& os, bool is_top) const {
+
+    template<typename OutputIt>
+    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<iterator_t> iter;
   };
@@ -2475,3 +2475,14 @@ template <typename NodeType>
 using node_to_stage_t = typename _node_to_stage_t<NodeType>::type;
 
 }
+
+template<typename T>
+concept HasDoFormatTo = requires(T x, std::back_insert_iterator<fmt::memory_buffer> out) {
+  { x.do_format_to(out, true) } -> std::same_as<decltype(out)>;
+};
+template <HasDoFormatTo T> struct fmt::formatter<T> : fmt::formatter<std::string_view> {
+  template <typename FormatContext>
+  auto format(const T& staged_iterator, FormatContext& ctx) {
+    return staged_iterator.do_format_to(ctx.out(), true);
+  }
+};