-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
Plugin system #599
Comments
Could you provide a concrete example of such an extension? |
Here are some examples. They're pretty minimal one but i think you'd get the idea of what you'd be able to do. First, here's an example of overloaded the value() function for a specific class, allowing extra parsing in order to find the right way to create the class. (the following is pseudo code as I don't actually have this in my json file) // template specialization for reading blob class from json
template <>
BlobClass value(const typename object_t::key_type& key, BlobClass default_value) const
{
if (find(key+"_file")) return BlobClassFromFile(this->operator[](key+"_file"));
else if (find(key+"_raw")) return BlobClassFromBase64EncodedString(this->operator[](key+"_raw"))
else
return BlobClassFromString(this->operator[](key));
} There are other examples related to interfacing the json class with external classes. There are also, of course, some simple functions to add that could otherwise be put into a pull request, but maybe they aren't so necessary to get put into the main repo, so this would allow people to add these functions locally. Here, for example, are two that I have: // similar to at(), but nonconst, and allows a default argument which is placed in the object if the key is not found
reference at(const typename object_t::key_type& key, const_reference def)
{
// at only works for objects
if (is_object())
{
JSON_TRY
{
return m_value.object->at(key);
}
JSON_CATCH (std::out_of_range&)
{
JSON_TRY
{
this->operator[](key) = def;
return m_value.object->at(key);
}
JSON_CATCH (std::out_of_range&)
{
// create better exception explanation
JSON_THROW(std::out_of_range("key '" + key + "' not found"));
}
}
}
else
{
JSON_THROW(std::domain_error("cannot use at() with " + type_name()));
}
}
// simple contains function
bool contains(const typename object_t::key_type& key) const
{
return find(key) != end();
} |
I like this idea. |
So you would literally add the lines #ifdef PLUGIN
#include PLUGIN
#endif to the beginning of the |
I'm thinking it would look like
probably at the end of |
Why is this better than subclassing? Using preprocessor tricks can lead to bugs in ODR (eg, if one file #define's the macro, but another file does not; or if you link two libraries together that have differening things in them). |
Yes, it would look just like It would probably go at the end of basic_json. You can see examples of a plugin system in Eigen and CImg, both very mature header-only c++ libraries. @jaredgrubb : this is better than subclassing because of functions returning references. The json class returns references in the form json& -- if you make a class JsonSubclass : public nlohmann::json, there is no way to make the nlohmann::json functiosn return a JsonSubclass& rather than a json&. |
Maybe related: #456 |
@an-kumar I'm still not really convinced that we need to rely on a preprocessor hack to solve a C++ problem that should have simpler solutions. Are you sure that the reference example you gave is impossible without code injection? |
Another question I have for this: There a several classes inside the |
I don't know of another way to do the reference example. Would love to hear a different solution there. As for the several classes inside basic_json -- yeah, this is a bit of an annoying issue. The way Eigen does this is they have a number of plugin definitions (e.g MATRIXBASE_PLUGIN, DENSEBASE_PLUGIN, etc) for the different classes. |
Many header-only libraries (for example, cimg) include 'plugin' systems, where people can add functionality to the class. It looks something like this:
Could we add something like this to this json library? I have some added functions that force me to maintain a version of json.hpp checked into my repo, but this makes it awkward to merge in updates to this repo.
The text was updated successfully, but these errors were encountered: