|
117 | 117 | # define FMT_NOINLINE |
118 | 118 | #endif |
119 | 119 |
|
| 120 | +// Detect constexpr std::string. |
| 121 | +#if !FMT_USE_CONSTEVAL |
| 122 | +# define FMT_USE_CONSTEXPR_STRING 0 |
| 123 | +#elif defined(__cpp_lib_constexpr_string) && \ |
| 124 | + __cpp_lib_constexpr_string >= 201907L |
| 125 | +# if FMT_CLANG_VERSION && FMT_GLIBCXX_RELEASE |
| 126 | +// clang + libstdc++ are able to work only starting with gcc13.3 |
| 127 | +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113294 |
| 128 | +# if FMT_GLIBCXX_RELEASE < 13 |
| 129 | +# define FMT_USE_CONSTEXPR_STRING 0 |
| 130 | +# elif FMT_GLIBCXX_RELEASE == 13 && __GLIBCXX__ < 20240521 |
| 131 | +# define FMT_USE_CONSTEXPR_STRING 0 |
| 132 | +# else |
| 133 | +# define FMT_USE_CONSTEXPR_STRING 1 |
| 134 | +# endif |
| 135 | +# else |
| 136 | +# define FMT_USE_CONSTEXPR_STRING 1 |
| 137 | +# endif |
| 138 | +#else |
| 139 | +# define FMT_USE_CONSTEXPR_STRING 0 |
| 140 | +#endif |
| 141 | +#if FMT_USE_CONSTEXPR_STRING |
| 142 | +# define FMT_CONSTEXPR_STRING constexpr |
| 143 | +#else |
| 144 | +# define FMT_CONSTEXPR_STRING |
| 145 | +#endif |
| 146 | + |
120 | 147 | // GCC 4.9 doesn't support qualified names in specializations. |
121 | 148 | namespace std { |
122 | 149 | template <typename T> struct iterator_traits<fmt::basic_appender<T>> { |
@@ -4207,21 +4234,23 @@ FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args) |
4207 | 4234 | * std::string answer = fmt::to_string(42); |
4208 | 4235 | */ |
4209 | 4236 | template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)> |
4210 | | -FMT_NODISCARD auto to_string(T value) -> std::string { |
| 4237 | +FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(T value) -> std::string { |
4211 | 4238 | // The buffer should be large enough to store the number including the sign |
4212 | 4239 | // or "false" for bool. |
4213 | 4240 | char buffer[max_of(detail::digits10<T>() + 2, 5)]; |
4214 | 4241 | return {buffer, detail::write<char>(buffer, value)}; |
4215 | 4242 | } |
4216 | 4243 |
|
4217 | 4244 | template <typename T, FMT_ENABLE_IF(detail::use_format_as<T>::value)> |
4218 | | -FMT_NODISCARD auto to_string(const T& value) -> std::string { |
| 4245 | +FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value) |
| 4246 | + -> std::string { |
4219 | 4247 | return to_string(format_as(value)); |
4220 | 4248 | } |
4221 | 4249 |
|
4222 | 4250 | template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value && |
4223 | 4251 | !detail::use_format_as<T>::value)> |
4224 | | -FMT_NODISCARD auto to_string(const T& value) -> std::string { |
| 4252 | +FMT_NODISCARD FMT_CONSTEXPR_STRING auto to_string(const T& value) |
| 4253 | + -> std::string { |
4225 | 4254 | auto buffer = memory_buffer(); |
4226 | 4255 | detail::write<char>(appender(buffer), value); |
4227 | 4256 | return {buffer.data(), buffer.size()}; |
|
0 commit comments