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 <boost/filesystem.hpp>
12 #include <filesystem>
13 
28 #if defined(FMT_VERSION) && FMT_VERSION >= 100000
29 # define FMT_CONST_IF_REQUIRED const
30 #else
31 # define FMT_CONST_IF_REQUIRED
32 #endif
33 
37 template<>
38 struct fmt::formatter<boost::filesystem::path> : fmt::formatter<std::string>
39 {
40  template<typename FormatContext>
41  auto format(const boost::filesystem::path & p, FormatContext & ctx) FMT_CONST_IF_REQUIRED
42  {
43  return fmt::formatter<std::string>::format(p.string(), ctx);
44  }
45 };
46 
50 template<>
51 struct fmt::formatter<std::filesystem::path> : fmt::formatter<std::string>
52 {
53  template<typename FormatContext>
54  auto format(const std::filesystem::path & p, FormatContext & ctx) FMT_CONST_IF_REQUIRED
55  {
56  return fmt::formatter<std::string>::format(p.string(), ctx);
57  }
58 };
59 
60 #if FMT_VERSION >= 9 * 10000
65 # define MC_FMT_STREAMED(X) fmt::streamed(X)
66 
67 // Formatter for any Eigen type derived from EigenBase (matrices, arrays,
68 // expressions, etc.) Tested for fmt_9, fmt_10, fmt_11 and fmt_12
69 template<typename T>
70 struct fmt::formatter<T, char, std::enable_if_t<std::is_base_of_v<Eigen::EigenBase<T>, T>>> : fmt::ostream_formatter
71 {
72 };
73 
74 // Prevent fmt/ranges from also treating Eigen types as ranges. Otherwise fmt
75 // finds two competing formatter specializations (ranges + Eigen ostream) and
76 // fails with an ambiguous formatter instantiation.
77 template<typename T, typename Char>
78 struct fmt::range_format_kind<T, Char, std::enable_if_t<std::is_base_of_v<Eigen::EigenBase<T>, T>>>
79 : std::integral_constant<fmt::range_format, fmt::range_format::disabled>
80 {
81 };
82 
83 # define MC_FMT_OSTREAM_FORMATTER(TYPE) \
84  template<> \
85  struct fmt::formatter<TYPE> : fmt::ostream_formatter \
86  { \
87  };
88 
89 // Automatic ostream formatter for SpaceVecAlg types
90 MC_FMT_OSTREAM_FORMATTER(sva::ABInertiad)
91 MC_FMT_OSTREAM_FORMATTER(sva::AdmittanceVecd)
92 MC_FMT_OSTREAM_FORMATTER(sva::ForceVecd)
93 MC_FMT_OSTREAM_FORMATTER(sva::MotionVecd)
94 MC_FMT_OSTREAM_FORMATTER(sva::RBInertiad)
95 MC_FMT_OSTREAM_FORMATTER(sva::PTransformd)
96 MC_FMT_OSTREAM_FORMATTER(sva::ImpedanceVecd)
97 #else // FMT_VERSION < 9 * 10000
98 /* std::ostream support was automatic in fmt versions < 9,
99  thus fmt::streamed did not exist and was not needed (which IMHO was a much
100  saner default) */
101 # define MC_FMT_STREAMED(X) X
102 #endif