Skip to content

Commit 7b4df9e

Browse files
committed
If the patch is an rvalue, move values away from it
1 parent 49858a2 commit 7b4df9e

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

include/tao/json/patch.hh

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)