@@ -48,11 +48,53 @@ namespace tao
4848 }
4949
5050 template < template < typename ... > class Traits >
51- basic_value< Traits > patch ( const basic_value< Traits > & value, const basic_value< Traits > & patch )
51+ void patch_inplace ( basic_value< Traits > & value, basic_value< Traits > & & patch )
5252 {
53- basic_value< Traits > result = value;
54- patch_inplace ( result, patch );
55- return result;
53+ for ( const auto & entry : patch.get_array () ) {
54+ const auto & op = entry.at ( " op" ).get_string ();
55+ const json_pointer path ( entry.at ( " path" ).get_string () );
56+ if ( op == " test" ) {
57+ if ( value.at ( path ) != entry.at ( " value" ) ) {
58+ throw std::runtime_error ( " test failed for: " + path.value () );
59+ }
60+ }
61+ else if ( op == " remove" ) {
62+ value.erase ( path );
63+ }
64+ else if ( op == " add" ) {
65+ value.insert ( path, std::move ( entry.at ( " value" ) ) );
66+ }
67+ else if ( op == " replace" ) {
68+ value.at ( path ) = std::move ( entry.at ( " value" ) );
69+ }
70+ else if ( op == " move" ) {
71+ const json_pointer from ( entry.at ( " from" ).get_string () );
72+ auto v = std::move ( value.at ( from ) );
73+ value.erase ( from );
74+ value.insert ( path, std::move ( v ) );
75+ }
76+ else if ( op == " copy" ) {
77+ const json_pointer from ( entry.at ( " from" ).get_string () );
78+ value.insert ( path, value.at ( from ) );
79+ }
80+ else {
81+ throw std::runtime_error ( " unknown patch operation: '" + op + ' \' ' );
82+ }
83+ }
84+ }
85+
86+ template < template < typename ... > class Traits >
87+ basic_value< Traits > patch ( basic_value< Traits > value, const basic_value< Traits > & patch )
88+ {
89+ patch_inplace ( value, patch );
90+ return std::move ( value );
91+ }
92+
93+ template < template < typename ... > class Traits >
94+ basic_value< Traits > patch ( basic_value< Traits > value, basic_value< Traits > && patch )
95+ {
96+ patch_inplace ( value, std::move ( patch ) );
97+ return std::move ( value );
5698 }
5799
58100 } // json
0 commit comments