@@ -317,14 +317,14 @@ using native_conversion_category = mp11::mp_cond<
317317 std::is_same<T, string>, string_conversion_tag>;
318318
319319// generic conversions
320- template < class T >
320+ template < class T , class Ctx >
321321using generic_conversion_category = mp11::mp_cond<
322322 std::is_same<T, bool >, bool_conversion_tag,
323323 std::is_integral<T>, integral_conversion_tag,
324324 std::is_floating_point<T>, floating_point_conversion_tag,
325325 is_null_like<T>, null_like_conversion_tag,
326326 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,
328328 is_sequence_like<T>, sequence_conversion_tag,
329329 is_tuple_like<T>, tuple_conversion_tag,
330330 is_described_class<T>, described_class_conversion_tag,
@@ -338,38 +338,57 @@ using generic_conversion_category = mp11::mp_cond<
338338template < class T >
339339using nested_type = typename T::type;
340340template < 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<
342342 std::is_same<detail::no_conversion_tag, T1>,
343343 T1,
344344 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+
345349template < class Ctx , class T , class Dir >
346- struct conversion_category_impl
350+ struct conversion_attrs
347351{
348- using type = mp11::mp_fold<
352+ using representation = representation_helper<T, Ctx>;
353+
354+ using category = mp11::mp_fold<
349355 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 >>,
353359 no_conversion_tag,
354- conversion_category_impl_helper >;
360+ conversion_category_helper >;
355361};
356- template < class Ctx , class T , class Dir >
357- using conversion_category =
358- typename conversion_category_impl< Ctx, T, Dir >::type;
359362
360363template < class T >
361364using any_conversion_tag = mp11::mp_not<
362365 std::is_same< T, no_conversion_tag > >;
363366
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+
364373template < 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 >
366375{
376+ using size = mp11::mp_size_t < sizeof ...(Ctxs) >;
367377 using ctxs = mp11::mp_list< remove_cvref<Ctxs>... >;
368- using cats = mp11::mp_list<
369- conversion_category<remove_cvref<Ctxs>, T, Dir>... >;
370378
371379 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>... >;
373392
374393 using context2 = mp11::mp_find< cats, full_context_conversion_tag >;
375394 using context1 = mp11::mp_find< cats, context_conversion_tag >;
@@ -379,7 +398,7 @@ struct conversion_category_impl< std::tuple<Ctxs...>, T, Dir >
379398 exists<context1>, context1,
380399 exists<context0>, context0,
381400 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<
383402 no_conversion_tag,
384403 mp11::mp_at, cats, index >;
385404};
@@ -459,10 +478,10 @@ template< class T, class Dir, class... Ctxs >
459478struct supported_context < std::tuple<Ctxs...>, T, Dir >
460479{
461480 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;
464483 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 >;
466485 using type = typename next_supported::type;
467486
468487 static
@@ -511,12 +530,14 @@ struct is_sequence_like
511530 mp11::mp_valid<detail::begin_iterator_category, T>>
512531{ };
513532
514- template <class T >
533+ template <class T , class Ctx >
515534struct is_map_like
516535 : mp11::mp_all<
517536 is_sequence_like<T>,
518537 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>>,
520541 mp11::mp_valid_and_true<detail::has_unique_keys, T>>
521542{ };
522543
@@ -566,6 +587,11 @@ struct is_optional_like
566587 mp11::mp_valid<detail::can_reset, T>>
567588{ };
568589
590+ template < class T >
591+ struct represent_as <T, detail::no_context>
592+ : represent_as<T, void >
593+ { };
594+
569595} // namespace json
570596} // namespace boost
571597
0 commit comments