From b4c4c812db6634bbcc4e7388c5f298cd834c0898 Mon Sep 17 00:00:00 2001 From: Darrell Wright Date: Sat, 7 Jan 2023 23:45:04 -0500 Subject: [PATCH] Fixed overconstraint on to_json, added round trip to base clss example --- extern/CMakeLists.txt | 2 +- include/daw/json/impl/to_daw_json_string.h | 3 +- tests/src/base_child_class_test.cpp | 80 ++++++++++++++-------- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 57fef58cc..1dfa96121 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -17,7 +17,7 @@ include( FetchContent ) FetchContent_Declare( daw_header_libraries GIT_REPOSITORY https://github.com/beached/header_libraries.git - GIT_TAG v2.80.0 + GIT_TAG v2.84.1 ) FetchContent_Declare( diff --git a/include/daw/json/impl/to_daw_json_string.h b/include/daw/json/impl/to_daw_json_string.h index 167e6a0ad..8e33d4b4a 100644 --- a/include/daw/json/impl/to_daw_json_string.h +++ b/include/daw/json/impl/to_daw_json_string.h @@ -933,7 +933,8 @@ namespace daw::json { to_json_string_class( WriteableType it, parse_to_t const &value ) { static_assert( - std::is_convertible_v, + std::is_convertible_v or + std::is_same_v, // This is for not-copy/movable types "value must be convertible to specified type in class contract" ); if constexpr( has_json_to_json_data_v ) { diff --git a/tests/src/base_child_class_test.cpp b/tests/src/base_child_class_test.cpp index 6189bb7fe..00b0bdc76 100644 --- a/tests/src/base_child_class_test.cpp +++ b/tests/src/base_child_class_test.cpp @@ -6,9 +6,11 @@ // Official repository: https://github.com/beached/daw_json_link // +#include "defines.h" + #include -#include +#include #include #include @@ -22,75 +24,90 @@ struct Base { [[nodiscard]] virtual int type( ) const = 0; [[nodiscard]] virtual int value( ) const = 0; + [[nodiscard]] virtual std::string to_json( ) const = 0; }; struct Child0 : Base { + int t; int v; - explicit Child0( int V ) noexcept - : v( V ) {} + explicit Child0( int Type, int V ) noexcept + : t( Type ) + , v( V ) {} [[nodiscard]] int type( ) const override { - return 0; + return t; } [[nodiscard]] int value( ) const override { return v; } + + [[nodiscard]] std::string to_json( ) const override; }; namespace daw::json { template<> struct json_data_contract { + static constexpr char const type_mem[] = "type"; static constexpr char const v[] = "v"; - using type = json_member_list>; + using type = + json_member_list, json_number>; static constexpr auto to_json_data( Child0 const &c0 ) { - return std::forward_as_tuple( c0.v ); + return std::forward_as_tuple( c0.t, c0.v ); } }; } // namespace daw::json +[[nodiscard]] std::string Child0::to_json( ) const { + return daw::json::to_json( *this ); +} + struct Child1 : Base { + int t; int d; - explicit Child1( int D ) noexcept - : d( D ) {} + explicit Child1( int Type, int D ) noexcept + : t( Type ) + , d( D ) {} [[nodiscard]] int type( ) const override { - return 1; + return t; } [[nodiscard]] int value( ) const override { return d; } + + [[nodiscard]] std::string to_json( ) const override; }; namespace daw::json { template<> struct json_data_contract { static constexpr char const d[] = "d"; - using type = json_member_list>; + static constexpr char const type_mem[] = "type"; + using type = + json_member_list, json_number>; static constexpr auto to_json_data( Child1 const &c1 ) { - return std::forward_as_tuple( c1.d ); + return std::forward_as_tuple( c1.t, c1.d ); } }; } // namespace daw::json -struct Switcher { - // Convert JSON tag member to type index - constexpr size_t operator( )( int type ) const { - return static_cast( type ); - } - // Get value for Tag from class value - int operator( )( Base const &b ) const { - return static_cast( b.type( ) ); - } -}; +[[nodiscard]] std::string Child1::to_json( ) const { + return daw::json::to_json( *this ); +} struct Foo { std::unique_ptr value; + + [[nodiscard]] bool operator==( Foo const &rhs ) const noexcept { + return value->type( ) == rhs.value->type( ) and + value->value( ) == rhs.value->value( ); + } }; struct FooMaker { @@ -115,6 +132,10 @@ namespace daw::json { static constexpr char const value[] = "value"; using type = json_member_list, FooMaker>>; + + [[nodiscard]] static auto to_json_data( Foo const &foo ) { + return std::tuple{ foo.value->to_json( ) }; + } }; } // namespace daw::json @@ -128,10 +149,15 @@ constexpr std::string_view json_doc = R"json( int main( ) { auto foo = daw::json::from_json>( json_doc ); - assert( foo[0].value->type( ) == 0 ); - assert( foo[0].value->value( ) == 42 ); - assert( foo[1].value->type( ) == 1 ); - assert( foo[1].value->value( ) == 66 ); - assert( foo[2].value->type( ) == 0 ); - assert( foo[2].value->value( ) == 77 ); + ensure( foo[0].value->type( ) == 0 ); + ensure( foo[0].value->value( ) == 42 ); + ensure( foo[1].value->type( ) == 1 ); + ensure( foo[1].value->value( ) == 66 ); + ensure( foo[2].value->type( ) == 0 ); + ensure( foo[2].value->value( ) == 77 ); + + auto str = daw::json::to_json( foo ); + std::cout << str << '\n'; + auto foo2 = daw::json::from_json>( str ); + ensure( foo == foo2 ); }