@@ -248,7 +248,8 @@ void test_visit_monostate() {
248
248
249
249
template <class Context >
250
250
void test_lwg3810 () {
251
- [[maybe_unused]] auto args_store = make_format_args<Context>(1 , 2 , 3 );
251
+ int args[]{1 , 2 , 3 };
252
+ [[maybe_unused]] auto args_store = make_format_args<Context>(args[0 ], args[1 ], args[2 ]);
252
253
static_assert (same_as<decltype (basic_format_args{args_store}), basic_format_args<Context>>);
253
254
}
254
255
@@ -264,6 +265,54 @@ void test_lvalue_only_visitation() {
264
265
visit_format_arg (lvalue_only_visitor{}, basic_format_arg<Context>{});
265
266
}
266
267
268
+ namespace detail {
269
+ constexpr bool permissive () {
270
+ return false ;
271
+ }
272
+
273
+ template <class >
274
+ struct DependentBase {
275
+ static constexpr bool permissive () {
276
+ return true ;
277
+ }
278
+ };
279
+
280
+ template <class T >
281
+ struct Derived : DependentBase<T> {
282
+ static constexpr bool test () {
283
+ return permissive ();
284
+ }
285
+ };
286
+ } // namespace detail
287
+ constexpr bool is_permissive = detail::Derived<int >::test();
288
+
289
+ template <class Context , class ... Args>
290
+ concept CanMakeFormatArgs = requires (Args&&... args) { make_format_args<Context>(static_cast <Args&&>(args)...); };
291
+
292
+ // P2905R2 Runtime format strings (make make_(w)format_args only take lvalue references)
293
+ template <class Context >
294
+ void test_lvalue_reference_parameters () {
295
+ using char_type = Context::char_type;
296
+
297
+ static_assert (CanMakeFormatArgs<Context, int &, long long &, double &, char_type&, char_type*&, const char_type*&,
298
+ basic_string<char_type>&, basic_string_view<char_type>&>);
299
+ static_assert (
300
+ CanMakeFormatArgs<Context, const int &, const long long &, const double &, const char_type&, char_type* const &,
301
+ const char_type* const &, const basic_string<char_type>&, const basic_string_view<char_type>&>);
302
+
303
+ static_assert (CanMakeFormatArgs<Context, const int , const long long , const double , const char_type,
304
+ char_type* const , const char_type* const , const basic_string<char_type>, const basic_string_view<char_type>>);
305
+
306
+ static_assert (!CanMakeFormatArgs<Context, int >);
307
+ static_assert (!CanMakeFormatArgs<Context, long long >);
308
+ static_assert (!CanMakeFormatArgs<Context, double >);
309
+ static_assert (!CanMakeFormatArgs<Context, char_type>);
310
+ static_assert (!CanMakeFormatArgs<Context, char_type*>);
311
+ static_assert (!CanMakeFormatArgs<Context, const char_type*>);
312
+ static_assert (CanMakeFormatArgs<Context, basic_string<char_type>> == is_permissive);
313
+ static_assert (CanMakeFormatArgs<Context, basic_string_view<char_type>> == is_permissive);
314
+ }
315
+
267
316
int main () {
268
317
test_basic_format_arg<format_context>();
269
318
test_basic_format_arg<wformat_context>();
@@ -277,4 +326,7 @@ int main() {
277
326
278
327
test_lvalue_only_visitation<format_context>();
279
328
test_lvalue_only_visitation<wformat_context>();
329
+
330
+ test_lvalue_reference_parameters<format_context>();
331
+ test_lvalue_reference_parameters<wformat_context>();
280
332
}
0 commit comments