1616
1717#include < __concepts/arithmetic.h>
1818#include < __concepts/same_as.h>
19+ #include < __concepts/semiregular.h>
1920#include < __config>
2021#include < __format/concepts.h>
2122#include < __format/format_arg.h>
2223#include < __type_traits/conditional.h>
2324#include < __type_traits/extent.h>
25+ #include < __type_traits/is_assignable.h>
26+ #include < __type_traits/is_constructible.h>
2427#include < __type_traits/remove_const.h>
2528#include < cstdint>
2629#include < string>
@@ -227,16 +230,6 @@ template <class _Context, class _Tp>
227230 { __f.parse (__pc) } -> same_as<typename decltype (__pc)::iterator>;
228231 };
229232
230- constexpr bool __has_format_function = requires (_Formatter& __f, _Tp&& __t , _Context __fc) {
231- { __f.format (__t , __fc) };
232- };
233- constexpr bool __is_format_function_const_qualified = requires (const _Formatter& __cf, _Tp&& __t , _Context __fc) {
234- { __cf.format (__t , __fc) };
235- };
236- constexpr bool __correct_format_function_return_type = requires (_Formatter& __f, _Tp&& __t , _Context __fc) {
237- { __f.format (__t , __fc)->same_as <typename _Context::iterator> };
238- };
239-
240233 // The reason these static_asserts are placed in an if-constexpr-chain is to
241234 // only show one error. For example, when the formatter is not specialized it
242235 // would show all static_assert messages. With this chain the compiler only
@@ -253,17 +246,37 @@ template <class _Context, class _Tp>
253246 else if constexpr (!__correct_parse_function_return_type)
254247 static_assert (false , " The required formatter specialization's parse function does not return the required type." );
255248
256- else if constexpr (!__has_format_function)
257- static_assert (
258- false , " The required formatter specialization does not have a format function taking the proper arguments." );
259- else if constexpr (!__is_format_function_const_qualified)
260- static_assert (false , " The required formatter specialization's format function is not const qualified." );
261- else if constexpr (!__correct_format_function_return_type)
262- static_assert (false , " The required formatter specialization's format function does not return the required type." );
249+ else {
250+ // During constant evaluation this function is called, but the format
251+ // member function has not been evaluated. This means these functions
252+ // can't be evaluated at that time.
253+ //
254+ // Note this else branch should never been taken during constant
255+ // eveluation, the static_asserts in one of the branches above should
256+ // trigger.
257+ constexpr bool __has_format_function = requires (_Formatter& __f, _Tp&& __t , _Context __fc) {
258+ { __f.format (__t , __fc) };
259+ };
260+ constexpr bool __is_format_function_const_qualified = requires (const _Formatter& __cf, _Tp&& __t , _Context __fc) {
261+ { __cf.format (__t , __fc) };
262+ };
263+ constexpr bool __correct_format_function_return_type = requires (_Formatter& __f, _Tp&& __t , _Context __fc) {
264+ { __f.format (__t , __fc)->same_as <typename _Context::iterator> };
265+ };
266+
267+ if constexpr (!__has_format_function)
268+ static_assert (
269+ false , " The required formatter specialization does not have a format function taking the proper arguments." );
270+ else if constexpr (!__is_format_function_const_qualified)
271+ static_assert (false , " The required formatter specialization's format function is not const qualified." );
272+ else if constexpr (!__correct_format_function_return_type)
273+ static_assert (
274+ false , " The required formatter specialization's format function does not return the required type." );
263275
264- else
265- // This should not happen; it makes sure the code is ill-formed.
266- static_assert (false , " The required formatter specialization is not formattable with its context." );
276+ else
277+ // This should not happen; it makes sure the code is ill-formed.
278+ static_assert (false , " The required formatter specialization is not formattable with its context." );
279+ }
267280}
268281
269282// The Psuedo constructor is constrained per [format.arg]/4.
0 commit comments