1111#define _LIBCPP___FORMAT_FORMAT_FUNCTIONS
1212
1313#include < __algorithm/clamp.h>
14+ #include < __algorithm/ranges_find_first_of.h>
15+ #include < __chrono/statically_widen.h>
1416#include < __concepts/convertible_to.h>
1517#include < __concepts/same_as.h>
1618#include < __config>
@@ -447,10 +449,41 @@ format_to(_OutIt __out_it, wformat_string<_Args...> __fmt, _Args&&... __args) {
447449}
448450# endif
449451
452+ template <class _CharT >
453+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI optional<basic_string<_CharT>> __try_constant_folding_format (
454+ basic_string_view<_CharT> __fmt,
455+ basic_format_args<basic_format_context<back_insert_iterator<__format::__output_buffer<_CharT>>, _CharT>> __args) {
456+ // [[gnu::pure]] is added to ensure that the compiler always knows that this call can be eliminated.
457+ if (bool __is_identity =
458+ [&] [[__gnu__::__pure__]] { return std::ranges::find_first_of (__fmt, array{' {' , ' }' }) == __fmt.end (); }();
459+ __builtin_constant_p (__is_identity) && __is_identity)
460+ return basic_string<_CharT>{__fmt};
461+
462+ if (auto __only_first_arg = __fmt == _LIBCPP_STATICALLY_WIDEN (_CharT, " {}" );
463+ __builtin_constant_p (__only_first_arg) && __only_first_arg) {
464+ if (auto __arg = __args.get (0 ); __builtin_constant_p (__arg.__type_ )) {
465+ return std::__visit_format_arg (
466+ []<class _Tp >(_Tp&& __argument) -> optional<basic_string<_CharT>> {
467+ if constexpr (is_same_v<remove_cvref_t <_Tp>, basic_string_view<_CharT>>) {
468+ return basic_string<_CharT>{__argument};
469+ } else {
470+ return nullopt ;
471+ }
472+ },
473+ __arg);
474+ }
475+ }
476+
477+ return nullopt ;
478+ }
479+
450480// TODO FMT This needs to be a template or std::to_chars(floating-point) availability markup
451481// fires too eagerly, see http://llvm.org/PR61563.
452482template <class = void >
453483[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI string vformat (string_view __fmt, format_args __args) {
484+ auto __result = std::__try_constant_folding_format (__fmt, __args);
485+ if (__result.has_value ())
486+ return *__result;
454487 __format::__allocating_buffer<char > __buffer;
455488 std::vformat_to (__buffer.__make_output_iterator (), __fmt, __args);
456489 return string{__buffer.__view ()};
@@ -462,6 +495,9 @@ template <class = void>
462495template <class = void >
463496[[nodiscard]] _LIBCPP_ALWAYS_INLINE inline _LIBCPP_HIDE_FROM_ABI wstring
464497vformat (wstring_view __fmt, wformat_args __args) {
498+ auto __result = std::__try_constant_folding_format (__fmt, __args);
499+ if (__result.has_value ())
500+ return *__result;
465501 __format::__allocating_buffer<wchar_t > __buffer;
466502 std::vformat_to (__buffer.__make_output_iterator (), __fmt, __args);
467503 return wstring{__buffer.__view ()};
0 commit comments