mc_rtc  2.14.0
fmt_formatters.h
Go to the documentation of this file.
1 /*
2  * Copyright 2026 CNRS-UM LIRMM, CNRS-AIST JRL
3  */
4 
5 #pragma once
6 #include <fmt/format.h>
7 #include <fmt/ostream.h>
8 #include <fmt/ranges.h>
9 
10 #include <SpaceVecAlg/SpaceVecAlg>
11 #include <filesystem>
12 
27 #if defined(FMT_VERSION) && FMT_VERSION >= 100000
28 # define FMT_CONST_IF_REQUIRED const
29 #else
30 # define FMT_CONST_IF_REQUIRED
31 #endif
32 
36 template<>
37 struct fmt::formatter<std::filesystem::path> : fmt::formatter<std::string>
38 {
39  template<typename FormatContext>
40  auto format(const std::filesystem::path & p, FormatContext & ctx) FMT_CONST_IF_REQUIRED
41  {
42  return fmt::formatter<std::string>::format(p.string(), ctx);
43  }
44 };
45 
46 #if FMT_VERSION >= 9 * 10000
51 # define MC_FMT_STREAMED(X) fmt::streamed(X)
52 
53 // Formatter for any Eigen type derived from EigenBase (matrices, arrays,
54 // expressions, etc.) Tested for fmt_9, fmt_10, fmt_11 and fmt_12
55 template<typename T>
56 struct fmt::formatter<T, char, std::enable_if_t<std::is_base_of_v<Eigen::EigenBase<T>, T>>> : fmt::ostream_formatter
57 {
58 };
59 
60 // Prevent fmt/ranges from also treating Eigen types as ranges. Otherwise fmt
61 // finds two competing formatter specializations (ranges + Eigen ostream) and
62 // fails with an ambiguous formatter instantiation.
63 template<typename T, typename Char>
64 struct fmt::range_format_kind<T, Char, std::enable_if_t<std::is_base_of_v<Eigen::EigenBase<T>, T>>>
65 : std::integral_constant<fmt::range_format, fmt::range_format::disabled>
66 {
67 };
68 
69 # define MC_FMT_OSTREAM_FORMATTER(TYPE) \
70  template<> \
71  struct fmt::formatter<TYPE> : fmt::ostream_formatter \
72  { \
73  };
74 
75 // Automatic ostream formatter for SpaceVecAlg types
76 MC_FMT_OSTREAM_FORMATTER(sva::ABInertiad)
77 MC_FMT_OSTREAM_FORMATTER(sva::AdmittanceVecd)
78 MC_FMT_OSTREAM_FORMATTER(sva::ForceVecd)
79 MC_FMT_OSTREAM_FORMATTER(sva::MotionVecd)
80 MC_FMT_OSTREAM_FORMATTER(sva::RBInertiad)
81 MC_FMT_OSTREAM_FORMATTER(sva::PTransformd)
82 MC_FMT_OSTREAM_FORMATTER(sva::ImpedanceVecd)
83 #else // FMT_VERSION < 9 * 10000
84 /* std::ostream support was automatic in fmt versions < 9,
85  thus fmt::streamed did not exist and was not needed (which IMHO was a much
86  saner default) */
87 # define MC_FMT_STREAMED(X) X
88 #endif