// Copyright (c) 2018-2020 Dr. Colin Hirsch and Daniel Frey // Please see LICENSE for license or visit https://github.com/taocpp/json/ #ifndef TAO_JSON_CONTRIB_SHARED_PTR_TRAITS_HPP #define TAO_JSON_CONTRIB_SHARED_PTR_TRAITS_HPP #include #include #include #include "../forward.hpp" #include "internal/indirect_traits.hpp" #include "internal/type_traits.hpp" namespace tao::json { namespace internal { template< typename T, typename U > struct shared_ptr_traits { template< template< typename... > class Traits, typename... With > [[nodiscard]] static auto as( const basic_value< Traits >& v, With&... with ) -> std::enable_if_t< use_first_ptr_as< T, Traits, With... >, std::shared_ptr< U > > { return std::make_shared< T >( v, with... ); } template< template< typename... > class Traits, typename... With > [[nodiscard]] static auto as( const basic_value< Traits >& v, With&... with ) -> std::enable_if_t< use_second_ptr_as< T, Traits, With... > || use_fourth_ptr_as< T, Traits, With... >, std::shared_ptr< U > > { return std::make_shared< T >( Traits< T >::as( v, with... ) ); } template< template< typename... > class Traits, typename... With > [[nodiscard]] static auto as( const basic_value< Traits >& v, With&... with ) -> std::enable_if_t< use_third_ptr_as< T, Traits, With... >, std::shared_ptr< U > > { auto t = std::make_shared< T >(); Traits< T >::to( v, *t, with... ); return t; } template< template< typename... > class Traits, typename Producer > [[nodiscard]] static auto consume( Producer& parser ) -> std::enable_if_t< use_first_ptr_consume< T, Traits, Producer > || use_third_ptr_consume< T, Traits, Producer >, std::shared_ptr< U > > { return Traits< T >::template consume< Traits >( parser ); } template< template< typename... > class Traits, typename Producer > [[nodiscard]] static auto consume( Producer& parser ) -> std::enable_if_t< use_second_ptr_consume< T, Traits, Producer >, std::shared_ptr< U > > { auto t = std::make_shared< T >(); Traits< T >::template consume< Traits >( parser, *t ); return t; } }; } // namespace internal template< typename T, typename U = T > struct shared_ptr_traits : internal::shared_ptr_traits< T, U > { template< template< typename... > class Traits > static void assign( basic_value< Traits >& v, const std::shared_ptr< U >& o ) { assert( o ); v = static_cast< const T& >( *o ); } template< template< typename... > class Traits, typename Consumer > static void produce( Consumer& c, const std::shared_ptr< U >& o ) { assert( o ); json::events::produce< Traits >( c, static_cast< const T& >( *o ) ); } }; template< typename T > struct shared_ptr_traits< T, T > : internal::shared_ptr_traits< T, T >, internal::indirect_traits< std::shared_ptr< T > > { template< typename V > using with_base = shared_ptr_traits< T, V >; }; } // namespace tao::json #endif