-
-
Notifications
You must be signed in to change notification settings - Fork 163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
variant of json_replace() that takes function object #279
Conversation
316b5f0
to
3da4a87
Compare
I think the goal for this pull request, to allow access to the vector of pointers, is worthwhile. But there's an issue with the approach. While typically the pointers in the vector are to values in the original json, there are also cases where the pointers are to instances created during the JSONPath evaluation and stored in a So one possible solution might be
|
Thank you for your quick response! |
I like your idea of a callback, and prefer it to my suggestion, because it exposes less implementation detail, and requires only an additional overload for template<class Json, class Op>
void json_replace(Json& root, const typename Json::string_view_type& path, Op op); with the signature of Json fun(const Json& a); We would need type requirements on the second template parameter Your example then becomes auto op = [](const json& val) {return std::round(val.as<double>() - 1.0);};
json_replace(booklist, "$.store.book[*].price", op); with What do you think? |
I tried to implement an overload of json_replace() but I found it pretty hard to distinguish between a callback and all the other possible types. So I wrote a function json_replace_fn() function instead.
I was a little disappointed that there is no such trait implementation already in the standard library. The only thing I found was std::is_function which does not work for callable objects but only for "real" functions. |
Regarding your second suggestion, implementing a trait class that detects callable types, try template<class FunctionObject, class Arg>
using
function_object_t = decltype(std::declval<FunctionObject>()(std::declval<Arg>()));
template<class FunctionObject, class Arg>
using
is_function_object = jsoncons::detail::is_detected<function_object_t, FunctionObject, Arg>;
template<class Json, class T>
typename std::enable_if<!is_function_object<T,Json>::value,void>::type
json_replace(Json& root, const typename Json::string_view_type& path, T&& new_value)
{
}
template<class Json, class Op>
typename std::enable_if<is_function_object<Op,Json>::value,void>::type
json_replace(Json& root, const typename Json::string_view_type& path, Op op)
{
} If that works, |
Now it is possible to use json_replace() to rewrite matched values with a callback function.
Wow! Thank you, that worked! |
Thanks for contributing! |
This makes it possible to change values depending on their previous values.
With json_replace() it is possible to replace a matched value with a new predefined value but it is not possible to rewrite the value depending on the previous value.
Getting the pointers of the matched values allows us to run search-and-replace rules on the old value to generate the new value.