Skip to content

Commit 648ab43

Browse files
committed
Continue experiment.
1 parent 2627190 commit 648ab43

File tree

4 files changed

+160
-12
lines changed

4 files changed

+160
-12
lines changed

include/tao/json/binding.hpp

Lines changed: 110 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,18 +364,49 @@ namespace tao
364364
}
365365
};
366366

367-
template< typename K, typename B >
367+
template< typename K, typename T, typename U >
368368
struct factory_type
369-
: public factory_name< K >,
370-
public B
369+
: public factory_name< K >
371370
{
371+
static const std::type_info* type()
372+
{
373+
return &typeid( T );
374+
}
375+
376+
template< template< typename... > class Traits, typename Base >
377+
static std::shared_ptr< U > as( const basic_value< Traits, Base >& v )
378+
{
379+
using R = typename Traits< std::shared_ptr< T > >::template with_base< U >;
380+
return R::as( v );
381+
}
382+
383+
template< template< typename... > class Traits, typename Base >
384+
static void assign( basic_value< Traits, Base >& v, const std::shared_ptr< U >& p )
385+
{
386+
using R = typename Traits< std::shared_ptr< T > >::template with_base< U >;
387+
R::assign( v, p );
388+
}
389+
390+
template< template< typename... > class Traits, typename Consumer >
391+
static void produce( Consumer& consumer, const std::shared_ptr< U >& p )
392+
{
393+
using R = typename Traits< std::shared_ptr< T > >::template with_base< U >;
394+
R::template produce< Traits >( consumer, p );
395+
}
396+
397+
template< template< typename... > class Traits, typename Producer >
398+
static std::shared_ptr< U > consume( Producer& producer )
399+
{
400+
using R = typename Traits< std::shared_ptr< T > >::template with_base< U >;
401+
return R::template consume< Traits >( producer );
402+
}
372403
};
373404

374405
template< typename K, typename T >
375406
struct factory_temp
376407
{
377-
template< typename U, template< typename... > class Traits >
378-
using type = factory_type< K, typename Traits< std::shared_ptr< T > >::template with_base< U > >;
408+
template< typename U >
409+
using bind = factory_type< K, T, U >;
379410
};
380411

381412
template< typename U, typename... Ts >
@@ -392,11 +423,24 @@ namespace tao
392423
F function;
393424
};
394425

426+
template< typename F >
427+
struct entry2
428+
{
429+
entry2( F c, const std::string& n )
430+
: function( c ),
431+
name( n )
432+
{
433+
}
434+
435+
F function;
436+
std::string name;
437+
};
438+
395439
template< typename V, template< typename... > class Traits, typename Base, typename F >
396440
static bool emplace_as( std::map< std::string, entry< F > >& m )
397441
{
398-
using T = typename V::template type< U, Traits >;
399-
m.emplace( T::name(), entry< F >( &T::template as< Traits, Base > ) );
442+
using W = typename V::template bind< U >;
443+
m.emplace( W::name(), entry< F >( &W::template as< Traits, Base > ) );
400444
return true;
401445
}
402446

@@ -422,6 +466,65 @@ namespace tao
422466
}
423467
return i->second.function( b->second );
424468
}
469+
470+
template< typename V, template< typename... > class Traits, typename Base, typename F >
471+
static bool emplace_assign( std::map< const std::type_info*, entry2< F >, json::internal::type_info_less >& m )
472+
{
473+
using W = typename V::template bind< U >;
474+
m.emplace( W::type(), entry2< F >( &W::template assign< Traits, Base >, W::name() ) );
475+
return true;
476+
}
477+
478+
template< template< typename... > class Traits, typename Base >
479+
static void assign( basic_value< Traits, Base >& v, const std::shared_ptr< U >& p )
480+
{
481+
using F = void ( * )( basic_value< Traits, Base >&, const std::shared_ptr< U >& );
482+
static const std::map< const std::type_info*, entry2< F >, json::internal::type_info_less > m = []() {
483+
std::map< const std::type_info*, entry2< F >, json::internal::type_info_less > t;
484+
(void)json::internal::swallow{ emplace_assign< Ts, Traits, Base >( t )... };
485+
assert( t.size() == sizeof...( Ts ) );
486+
return t;
487+
}();
488+
489+
const auto i = m.find( &typeid( *p ) );
490+
if( i == m.end() ) {
491+
throw std::runtime_error( "unknown factory type " + TAO_JSON_PEGTL_NAMESPACE::internal::demangle( typeid( *p ).name() ) ); // NOLINT
492+
}
493+
i->second.function( v, p );
494+
v = {
495+
{ i->second.name, std::move( v ) }
496+
};
497+
}
498+
499+
template< typename V, template< typename... > class Traits, typename Consumer, typename F >
500+
static bool emplace_produce( std::map< const std::type_info*, entry2< F >, json::internal::type_info_less >& m )
501+
{
502+
using W = typename V::template bind< U >;
503+
m.emplace( W::type(), entry2< F >( &W::template produce< Traits, Consumer >, W::name() ) );
504+
return true;
505+
}
506+
507+
template< template< typename... > class Traits, typename Consumer >
508+
static void produce( Consumer& consumer, const std::shared_ptr< U >& p )
509+
{
510+
using F = void ( * )( Consumer&, const std::shared_ptr< U >& );
511+
static const std::map< const std::type_info*, entry2< F >, json::internal::type_info_less > m = []() {
512+
std::map< const std::type_info*, entry2< F >, json::internal::type_info_less > t;
513+
(void)json::internal::swallow{ emplace_produce< Ts, Traits, Consumer >( t )... };
514+
assert( t.size() == sizeof...( Ts ) );
515+
return t;
516+
}();
517+
518+
const auto i = m.find( &typeid( *p ) );
519+
if( i == m.end() ) {
520+
throw std::runtime_error( "unknown factory type " + TAO_JSON_PEGTL_NAMESPACE::internal::demangle( typeid( *p ).name() ) ); // NOLINT
521+
}
522+
consumer.begin_object( 1 );
523+
consumer.key( i->second.name );
524+
i->second.function( consumer, p );
525+
consumer.member();
526+
consumer.end_object( 1 );
527+
}
425528
};
426529

427530
} // namespace binding

include/tao/json/internal/type_traits.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ namespace tao
1414
{
1515
namespace internal
1616
{
17+
struct type_info_less
18+
{
19+
bool operator()( const std::type_info* l, const std::type_info* r ) const
20+
{
21+
return l->before( *r );
22+
}
23+
};
24+
1725
template< typename T >
1826
struct is_basic_value
1927
: public std::false_type

include/tao/json/traits.hpp

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,18 +1038,55 @@ namespace tao
10381038
}
10391039
};
10401040

1041-
template< typename T, typename U = T >
1041+
template< typename T, typename U = void >
10421042
struct shared_traits
1043+
{
1044+
template< template< typename... > class Traits, typename Base >
1045+
static std::shared_ptr< U > as( const basic_value< Traits, Base >& v )
1046+
{
1047+
if( v.is_null() ) {
1048+
return std::shared_ptr< U >();
1049+
}
1050+
auto t = std::make_shared< T >(); // TODO: More control?
1051+
v.as( *t );
1052+
return t;
1053+
}
1054+
1055+
template< template< typename... > class Traits, typename Base >
1056+
static void assign( basic_value< Traits, Base >& v, const std::shared_ptr< U >& p )
1057+
{
1058+
if( p ) {
1059+
v = static_cast< const T& >( *p );
1060+
}
1061+
else {
1062+
v = null;
1063+
}
1064+
}
1065+
1066+
template< template< typename... > class Traits, typename Consumer >
1067+
static void produce( Consumer& c, const T& p )
1068+
{
1069+
if( p ) {
1070+
json::events::produce< Traits >( c, static_cast< const T& >( *p ) );
1071+
}
1072+
else {
1073+
json::events::produce< Traits >( c, null );
1074+
}
1075+
}
1076+
};
1077+
1078+
template< typename T >
1079+
struct shared_traits< T, void >
10431080
: public internal::indirect_traits_base< std::shared_ptr< T > >
10441081
{
10451082
template< typename V >
10461083
using with_base = shared_traits< T, V >;
10471084

10481085
template< template< typename... > class Traits, typename Base >
1049-
static std::shared_ptr< U > as( const basic_value< Traits, Base >& v )
1086+
static std::shared_ptr< T > as( const basic_value< Traits, Base >& v )
10501087
{
10511088
if( v.is_null() ) {
1052-
return std::shared_ptr< U >();
1089+
return std::shared_ptr< T >();
10531090
}
10541091
auto t = std::make_shared< T >(); // TODO: More control?
10551092
v.as( *t );

src/example/json/parsing.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -871,8 +871,8 @@ namespace tao
871871
template< typename V, template< typename... > class Traits, typename Producer, typename F >
872872
static bool emplace_consume( std::map< std::string, entry< F > >& m )
873873
{
874-
using T = typename V::template type< U, Traits >;
875-
m.emplace( T::name(), entry< F >( &T::template consume< Traits, Producer > ) );
874+
using W = typename V::template bind< U >;
875+
m.emplace( W::name(), entry< F >( &W::template consume< Traits, Producer > ) );
876876
return true;
877877
}
878878

0 commit comments

Comments
 (0)