@@ -317,14 +317,14 @@ using native_conversion_category = mp11::mp_cond<
317
317
std::is_same<T, string>, string_conversion_tag>;
318
318
319
319
// generic conversions
320
- template < class T >
320
+ template < class T , class Ctx >
321
321
using generic_conversion_category = mp11::mp_cond<
322
322
std::is_same<T, bool >, bool_conversion_tag,
323
323
std::is_integral<T>, integral_conversion_tag,
324
324
std::is_floating_point<T>, floating_point_conversion_tag,
325
325
is_null_like<T>, null_like_conversion_tag,
326
326
is_string_like<T>, string_like_conversion_tag,
327
- is_map_like<T>, map_like_conversion_tag,
327
+ is_map_like<T, Ctx>, map_like_conversion_tag,
328
328
is_sequence_like<T>, sequence_conversion_tag,
329
329
is_tuple_like<T>, tuple_conversion_tag,
330
330
is_described_class<T>, described_class_conversion_tag,
@@ -338,38 +338,57 @@ using generic_conversion_category = mp11::mp_cond<
338
338
template < class T >
339
339
using nested_type = typename T::type;
340
340
template < class T1 , class T2 >
341
- using conversion_category_impl_helper = mp11::mp_eval_if_not<
341
+ using conversion_category_helper = mp11::mp_eval_if_not<
342
342
std::is_same<detail::no_conversion_tag, T1>,
343
343
T1,
344
344
mp11::mp_eval_or_q, T1, mp11::mp_quote<nested_type>, T2>;
345
+
346
+ template < class T , class Ctx , class Def = T >
347
+ using representation_helper = mp11::mp_eval_or<Def, represent_as_t , T, Ctx>;
348
+
345
349
template < class Ctx , class T , class Dir >
346
- struct conversion_category_impl
350
+ struct conversion_attrs
347
351
{
348
- using type = mp11::mp_fold<
352
+ using representation = representation_helper<T, Ctx>;
353
+
354
+ using category = mp11::mp_fold<
349
355
mp11::mp_list<
350
- mp11::mp_defer<user_conversion_category, Ctx, T , Dir>,
351
- mp11::mp_defer<native_conversion_category, T >,
352
- mp11::mp_defer<generic_conversion_category, T >>,
356
+ mp11::mp_defer<user_conversion_category, Ctx, representation , Dir>,
357
+ mp11::mp_defer<native_conversion_category, representation >,
358
+ mp11::mp_defer<generic_conversion_category, representation, Ctx >>,
353
359
no_conversion_tag,
354
- conversion_category_impl_helper >;
360
+ conversion_category_helper >;
355
361
};
356
- template < class Ctx , class T , class Dir >
357
- using conversion_category =
358
- typename conversion_category_impl< Ctx, T, Dir >::type;
359
362
360
363
template < class T >
361
364
using any_conversion_tag = mp11::mp_not<
362
365
std::is_same< T, no_conversion_tag > >;
363
366
367
+ template < class Ctx , class T , class Dir >
368
+ using conversion_category = typename conversion_attrs<Ctx, T, Dir>::category;
369
+
370
+ template < class U >
371
+ using is_not_void = mp11::mp_bool< !std::is_same<void , U>::value >;
372
+
364
373
template < class T , class Dir , class ... Ctxs >
365
- struct conversion_category_impl < std::tuple<Ctxs...>, T, Dir >
374
+ struct conversion_attrs < std::tuple<Ctxs...>, T, Dir >
366
375
{
376
+ using size = mp11::mp_size_t < sizeof ...(Ctxs) >;
367
377
using ctxs = mp11::mp_list< remove_cvref<Ctxs>... >;
368
- using cats = mp11::mp_list<
369
- conversion_category<remove_cvref<Ctxs>, T, Dir>... >;
370
378
371
379
template < class I >
372
- using exists = mp11::mp_less< I, mp11::mp_size<cats> >;
380
+ using exists = mp11::mp_less<I, size>;
381
+
382
+ using reps = mp11::mp_list<
383
+ representation_helper< T, remove_cvref<Ctxs>, void >... >;
384
+ using r_index = mp11::mp_find_if< reps, is_not_void >;
385
+ using representation = mp11::mp_eval_if<
386
+ mp11::mp_not<exists<r_index>>,
387
+ T,
388
+ mp11::mp_at, reps, r_index>;
389
+
390
+ using cats = mp11::mp_list<
391
+ conversion_category<remove_cvref<Ctxs>, representation, Dir>... >;
373
392
374
393
using context2 = mp11::mp_find< cats, full_context_conversion_tag >;
375
394
using context1 = mp11::mp_find< cats, context_conversion_tag >;
@@ -379,7 +398,7 @@ struct conversion_category_impl< std::tuple<Ctxs...>, T, Dir >
379
398
exists<context1>, context1,
380
399
exists<context0>, context0,
381
400
mp11::mp_true, mp11::mp_find_if< cats, any_conversion_tag > >;
382
- using type = mp11::mp_eval_or<
401
+ using category = mp11::mp_eval_or<
383
402
no_conversion_tag,
384
403
mp11::mp_at, cats, index >;
385
404
};
@@ -459,10 +478,10 @@ template< class T, class Dir, class... Ctxs >
459
478
struct supported_context < std::tuple<Ctxs...>, T, Dir >
460
479
{
461
480
using Ctx = std::tuple<Ctxs...>;
462
- using impl = conversion_category_impl <Ctx, T, Dir>;
463
- using index = typename impl ::index;
481
+ using Attrs = conversion_attrs <Ctx, T, Dir>;
482
+ using index = typename Attrs ::index;
464
483
using next_supported = supported_context<
465
- mp11::mp_at< typename impl ::ctxs, index >, T, Dir >;
484
+ mp11::mp_at< typename Attrs ::ctxs, index >, T, Dir >;
466
485
using type = typename next_supported::type;
467
486
468
487
static
@@ -511,12 +530,14 @@ struct is_sequence_like
511
530
mp11::mp_valid<detail::begin_iterator_category, T>>
512
531
{ };
513
532
514
- template <class T >
533
+ template <class T , class Ctx >
515
534
struct is_map_like
516
535
: mp11::mp_all<
517
536
is_sequence_like<T>,
518
537
mp11::mp_valid_and_true<detail::is_value_type_pair, T>,
519
- is_string_like<detail::key_type<T>>,
538
+ is_string_like<
539
+ detail::representation_helper<
540
+ detail::remove_cvref< detail::key_type<T> >, Ctx>>,
520
541
mp11::mp_valid_and_true<detail::has_unique_keys, T>>
521
542
{ };
522
543
@@ -566,6 +587,11 @@ struct is_optional_like
566
587
mp11::mp_valid<detail::can_reset, T>>
567
588
{ };
568
589
590
+ template < class T >
591
+ struct represent_as <T, detail::no_context>
592
+ : represent_as<T, void >
593
+ { };
594
+
569
595
} // namespace json
570
596
} // namespace boost
571
597
0 commit comments