@@ -258,6 +258,60 @@ tag_invoke(
258258}
259259
260260
261+ struct id
262+ {
263+ static constexpr auto & id1 = " Id#1" ;
264+ static constexpr auto & id2 = " Id#2" ;
265+
266+ std::size_t n;
267+ };
268+
269+ bool
270+ operator <(id l, id r) noexcept
271+ {
272+ return l.n < r.n ;
273+ }
274+
275+ struct id_string_repr
276+ {
277+ std::size_t n;
278+
279+ id_string_repr (id x) noexcept
280+ : n(x.n)
281+ {}
282+
283+ id_string_repr (boost::json::string_view sv)
284+ {
285+ if ( sv.data () == id::id1 )
286+ n = 1 ;
287+ else if ( sv.data () == id::id2 )
288+ n = 2 ;
289+ else
290+ n = std::size_t (-1 );
291+ }
292+
293+ operator id () const noexcept
294+ {
295+ return {n};
296+ }
297+
298+ operator boost::json::string_view () const noexcept
299+ {
300+ switch (n)
301+ {
302+ case 1 : return boost::json::string_view (id::id1);
303+ case 2 : return boost::json::string_view (id::id2);
304+ default : return boost::json::string_view (" unknown" );
305+ }
306+ }
307+ };
308+
309+ struct T14
310+ {
311+ id i;
312+ };
313+ BOOST_DESCRIBE_STRUCT (T14, (), (i))
314+
261315} // namespace value_from_test_ns
262316
263317template <class T >
@@ -296,6 +350,12 @@ struct is_described_class<::value_from_test_ns::T11>
296350 : std::true_type
297351{ };
298352
353+ template <>
354+ struct represent_as <::value_from_test_ns::id>
355+ {
356+ using type = ::value_from_test_ns::id_string_repr;
357+ };
358+
299359namespace {
300360
301361template < class T , class ... Context >
@@ -404,6 +464,23 @@ class value_from_test
404464 value b = value_from ( a, ctx... );
405465 BOOST_TEST (b.is_null ());
406466 }
467+ {
468+ value jv = value_from ( value_from_test_ns::id{1 }, ctx... );
469+ BOOST_TEST ( jv == value (" Id#1" ) );
470+
471+ jv = value_from ( value_from_test_ns::id{2 }, ctx... );
472+ BOOST_TEST ( jv == value (" Id#2" ) );
473+
474+ jv = value_from (
475+ std::vector<value_from_test_ns::id>{ {1 }, {2 }, {2 }, {1 } },
476+ ctx... );
477+ BOOST_TEST (( jv == value{" Id#1" , " Id#2" , " Id#2" , " Id#1" } ));
478+
479+ jv = value_from (
480+ std::tuple<value_from_test_ns::id, int >{ {1 }, 12 },
481+ ctx... );
482+ BOOST_TEST (( jv == value{" Id#1" , 12 } ));
483+ }
407484 }
408485
409486 template < class ... Context >
@@ -447,6 +524,12 @@ class value_from_test
447524 BOOST_TEST (a.size () == c.as_array ().size ());
448525 BOOST_TEST (b.as_array ().size () == c.as_array ().size ());
449526 }
527+ {
528+ value jv = value_from (
529+ std::map<value_from_test_ns::id, int >{ {{1 }, 42 }, {{2 }, 43 } },
530+ ctx... );
531+ BOOST_TEST (( jv == object{ {" Id#1" , 42 }, {" Id#2" , 43 } } ));
532+ }
450533 }
451534
452535 template < class ... Context >
@@ -505,6 +588,9 @@ class value_from_test
505588 ::value_from_test_ns::E1 e1 = ::value_from_test_ns::E1 ::a;
506589 BOOST_TEST ( value_from ( e1 , ctx... ) == " a" );
507590
591+ jv = value_from ( value_from_test_ns::T14{ {1 } }, ctx... );
592+ BOOST_TEST (( jv == object{ {" i" , " Id#1" } } ));
593+
508594 e1 = ::value_from_test_ns::E1 ::b;
509595 BOOST_TEST ( value_from ( e1 , ctx... ) == " b" );
510596
@@ -524,6 +610,10 @@ class value_from_test
524610 BOOST_TEST ( jv == (value{1 , 2 , 3 , nullptr , 5 }) );
525611
526612 BOOST_TEST ( value_from ( std::nullopt , ctx... ).is_null () );
613+
614+ jv = value_from (
615+ std::optional<value_from_test_ns::id>( {1 } ), ctx... );
616+ BOOST_TEST ( jv == value (" Id#1" ) );
527617#endif
528618 }
529619
@@ -546,6 +636,12 @@ class value_from_test
546636 jv = value_from ( v, ctx... );
547637 BOOST_TEST (jv == " T5" );
548638
639+ jv = value_from (
640+ std::variant<int , value_from_test_ns::id>(
641+ value_from_test_ns::id{2 } ),
642+ ctx... );
643+ BOOST_TEST ( jv == value (" Id#2" ) );
644+
549645 BOOST_TEST ( value () == value_from ( std::monostate (), ctx... ) );
550646#endif // BOOST_NO_CXX17_HDR_VARIANT
551647 }
0 commit comments