@@ -196,6 +196,97 @@ tag_invoke(
196196    return  T11 ( jv.to_number <int >() );
197197}
198198
199+ struct  id 
200+ {
201+     static  constexpr  auto & id1 = " Id#1" 
202+     static  constexpr  auto & id2 = " Id#2" 
203+ 
204+     std::size_t  n;
205+ };
206+ 
207+ bool 
208+ operator ==(id l, id r) noexcept 
209+ {
210+     return  l.n  == r.n ;
211+ }
212+ 
213+ bool 
214+ operator !=(id l, id r) noexcept 
215+ {
216+     return  l.n  != r.n ;
217+ }
218+ 
219+ bool 
220+ operator <(id l, id r) noexcept 
221+ {
222+     return  l.n  < r.n ;
223+ }
224+ 
225+ struct  id_string_repr 
226+ {
227+     std::size_t  n;
228+ 
229+     id_string_repr (id x) noexcept 
230+         : n(x.n)
231+     {}
232+ 
233+     id_string_repr (boost::json::string_view sv)
234+     {
235+         if ( std::equal ( sv.begin (), sv.end (), id::id1) )
236+             n = 1 ;
237+         else  if ( std::equal ( sv.begin (), sv.end (), id::id2) )
238+             n = 2 ;
239+         else 
240+             throw  std::runtime_error ( " unknown id" 
241+     }
242+ 
243+     operator  id () const  noexcept 
244+     {
245+         return  {n};
246+     }
247+ 
248+     operator  boost::json::string_view () const  noexcept 
249+     {
250+         switch (n)
251+         {
252+         case  1 : return  boost::json::string_view (id::id1);
253+         case  2 : return  boost::json::string_view (id::id2);
254+         default : return  boost::json::string_view (" unknown" 
255+         }
256+     }
257+ };
258+ 
259+ struct  T12 
260+ {
261+     id i;
262+ };
263+ BOOST_DESCRIBE_STRUCT (T12, (), (i))
264+ 
265+ struct  as_string  {};
266+ 
267+ struct  int_as_string 
268+ {
269+     std::string s;
270+ 
271+     int_as_string (int  n) noexcept 
272+         : s( std::to_string(n) )
273+     {}
274+ 
275+     int_as_string (boost::json::string_view sv)
276+         : s(sv)
277+     {}
278+ 
279+     operator  int () const  noexcept 
280+     {
281+         return  std::atoi ( s.data () );
282+     }
283+ 
284+     operator  boost::json::string_view () const  noexcept 
285+     {
286+         return  s;
287+     }
288+ };
289+ 
199290} //  namespace value_to_test_ns
200291
201292namespace  std 
@@ -225,6 +316,18 @@ struct is_null_like<::value_to_test_ns::T1> : std::true_type { };
225316template <>
226317struct  is_described_class <::value_to_test_ns::T7> : std::true_type { };
227318
319+ template <>
320+ struct  represent_as <::value_to_test_ns::id>
321+ {
322+     using  type = ::value_to_test_ns::id_string_repr;
323+ };
324+ 
325+ template  <>
326+ struct  represent_as <int , value_to_test_ns::as_string>
327+ {
328+     using  type = ::value_to_test_ns::int_as_string;
329+ };
330+ 
228331template  <class  T , class  = void >
229332struct  can_apply_value_to 
230333    : std::false_type
@@ -335,6 +438,19 @@ class value_to_test
335438            BOOST_TEST_CONV ( arr, ctx... );
336439        }
337440
441+         BOOST_TEST ((
442+             value_to< std::vector<value_to_test_ns::id> >(
443+                 value{" Id#1" " Id#2" " Id#2" " Id#1" 
444+             == std::vector<value_to_test_ns::id>{{1 }, {2 }, {2 }, {1 }} ));
445+         BOOST_TEST ((
446+             value_to< std::tuple<value_to_test_ns::id, int > >(
447+                 value{" Id#1" 12 }, ctx... )
448+             == std::tuple<value_to_test_ns::id, int >{{1 }, 12 } ));
449+         BOOST_TEST ((
450+             value_to< std::map<value_to_test_ns::id, int > >(
451+                 value{ {" Id#1" 42 }, {" Id#2" 43 } }, ctx... )
452+             == std::map<value_to_test_ns::id, int >{ {{1 }, 42 }, {{2 }, 43 } } ));
453+ 
338454        //  mismatched type
339455        BOOST_TEST_THROWS_WITH_LOCATION (
340456            value_to<std::string>( value (), ctx... ));
@@ -464,6 +580,11 @@ class value_to_test
464580            BOOST_TEST ( e1  == ::value_to_test_ns::E1 ::b );
465581        }
466582
583+         BOOST_TEST ((
584+             value_to<value_to_test_ns::T12>(
585+                 value (object{ {" i" " Id#1" i 
586+             == value_to_test_ns::T12{ {1 } }.i  ));
587+ 
467588        BOOST_TEST_THROWS_WITH_LOCATION (
468589            value_to<::value_to_test_ns::E1 >( value (1 ), ctx... ));
469590        BOOST_TEST_THROWS_WITH_LOCATION (
@@ -506,6 +627,12 @@ class value_to_test
506627        value_to< std::nullopt_t  >(value ());
507628        BOOST_TEST_THROWS_WITH_LOCATION (
508629            value_to< std::nullopt_t  >( jv, ctx... ));
630+ 
631+         BOOST_TEST ((
632+             value_to< std::optional<value_to_test_ns::id> >(
633+                 value (" Id#1" 
634+             == std::optional<value_to_test_ns::id>(
635+                 value_to_test_ns::id{1 } ) ));
509636#endif 
510637    }
511638
@@ -550,6 +677,10 @@ class value_to_test
550677        using  V_T3_T1 = Variant<value_to_test_ns::T3, value_to_test_ns::T1>;
551678        auto  v_t3_t1 = value_to<V_T3_T1>( jv, ctx... );
552679        BOOST_TEST ( v_t3_t1.index () == 1  );
680+ 
681+         BOOST_TEST ((
682+             value_to< Variant<value_to_test_ns::id> >( value (" Id#2" 
683+             == Variant<value_to_test_ns::id>( value_to_test_ns::id{2 } )));
553684    }
554685
555686    template < class ... Context >
@@ -757,6 +888,13 @@ class value_to_test
757888    testUserConversion ( Context const & ... ctx )
758889    {
759890        value_to<value_to_test_ns::T2>( value (" T2" 
891+ 
892+         auto  id = value_to<value_to_test_ns::id>(
893+             value (" Id#1" 
894+         BOOST_TEST ( id.n  == 1  );
895+         id = value_to<value_to_test_ns::id>(
896+             value (" Id#2" 
897+         BOOST_TEST ( id.n  == 2  );
760898    }
761899
762900    void 
@@ -769,6 +907,19 @@ class value_to_test
769907            value_to<value_to_test_ns::T9>(
770908                value (), value_to_test_ns::custom_context () ),
771909            system::system_error);
910+ 
911+         BOOST_TEST ((
912+             value_to< std::map<int , int > >(
913+                 value{ {" 1" " 2" " 2" " 4" " 3" " 8" 
914+                 value_to_test_ns::as_string () )
915+             == std::map<int , int >{ {1 ,2 }, {2 ,4 }, {3 ,8 } } ));
916+         BOOST_TEST ((
917+             value_to< std::map<int , int > >(
918+                 value{ {" 1" " 2" " 2" " 4" " 3" " 6" 
919+                 std::make_tuple (
920+                     value_to_test_ns::as_string (),
921+                     value_to_test_ns::custom_context () ))
922+             == std::map<int , int >{ {1 ,2 }, {2 ,4 }, {3 ,6 } } ));
772923    }
773924
774925    struct  run_templated_tests 
0 commit comments