@@ -196,6 +196,97 @@ tag_invoke(
196
196
return T11 ( jv.to_number <int >() );
197
197
}
198
198
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
+
199
290
} // namespace value_to_test_ns
200
291
201
292
namespace std
@@ -225,6 +316,18 @@ struct is_null_like<::value_to_test_ns::T1> : std::true_type { };
225
316
template <>
226
317
struct is_described_class <::value_to_test_ns::T7> : std::true_type { };
227
318
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
+
228
331
template <class T , class = void >
229
332
struct can_apply_value_to
230
333
: std::false_type
@@ -335,6 +438,19 @@ class value_to_test
335
438
BOOST_TEST_CONV ( arr, ctx... );
336
439
}
337
440
441
+ BOOST_TEST ((
442
+ value_to< std::vector<value_to_test_ns::id> >(
443
+ value{" Id#1" , " Id#2" , " Id#2" , " Id#1" }, ctx... )
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
+
338
454
// mismatched type
339
455
BOOST_TEST_THROWS_WITH_LOCATION (
340
456
value_to<std::string>( value (), ctx... ));
@@ -464,6 +580,11 @@ class value_to_test
464
580
BOOST_TEST ( e1 == ::value_to_test_ns::E1 ::b );
465
581
}
466
582
583
+ BOOST_TEST ((
584
+ value_to<value_to_test_ns::T12>(
585
+ value (object{ {" i" , " Id#1" } }), ctx... ).i
586
+ == value_to_test_ns::T12{ {1 } }.i ));
587
+
467
588
BOOST_TEST_THROWS_WITH_LOCATION (
468
589
value_to<::value_to_test_ns::E1 >( value (1 ), ctx... ));
469
590
BOOST_TEST_THROWS_WITH_LOCATION (
@@ -506,6 +627,12 @@ class value_to_test
506
627
value_to< std::nullopt_t >(value ());
507
628
BOOST_TEST_THROWS_WITH_LOCATION (
508
629
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" ), ctx... )
634
+ == std::optional<value_to_test_ns::id>(
635
+ value_to_test_ns::id{1 } ) ));
509
636
#endif
510
637
}
511
638
@@ -550,6 +677,10 @@ class value_to_test
550
677
using V_T3_T1 = Variant<value_to_test_ns::T3, value_to_test_ns::T1>;
551
678
auto v_t3_t1 = value_to<V_T3_T1>( jv, ctx... );
552
679
BOOST_TEST ( v_t3_t1.index () == 1 );
680
+
681
+ BOOST_TEST ((
682
+ value_to< Variant<value_to_test_ns::id> >( value (" Id#2" ), ctx... )
683
+ == Variant<value_to_test_ns::id>( value_to_test_ns::id{2 } )));
553
684
}
554
685
555
686
template < class ... Context >
@@ -757,6 +888,13 @@ class value_to_test
757
888
testUserConversion ( Context const & ... ctx )
758
889
{
759
890
value_to<value_to_test_ns::T2>( value (" T2" ), ctx... );
891
+
892
+ auto id = value_to<value_to_test_ns::id>(
893
+ value (" Id#1" ), ctx... );
894
+ BOOST_TEST ( id.n == 1 );
895
+ id = value_to<value_to_test_ns::id>(
896
+ value (" Id#2" ), ctx... );
897
+ BOOST_TEST ( id.n == 2 );
760
898
}
761
899
762
900
void
@@ -769,6 +907,19 @@ class value_to_test
769
907
value_to<value_to_test_ns::T9>(
770
908
value (), value_to_test_ns::custom_context () ),
771
909
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 } } ));
772
923
}
773
924
774
925
struct run_templated_tests
0 commit comments