Extending pugixml (xml_node) functionality for another library #680
-
While working on the OpenXLSX library, I implemented
I found myself in need of implementing some additional functionality to find next child / sibling nodes based on node type (defaulting to pugi::node_element), and of course wrapper functions for anything referring to a node by name. My current implementation derives a class from I am absolutely not happy with my implementation, as it exposes the pugixml headers through library headers to the user of the library (and accordingly can cause conflicts with a local pugixml installation). Accordingly I am trying to improve it. Now in order to prepare packaging for linux distributions, I started looking into doing a pImpl idiom extension of pugixml that can work with an installed pugixml library.
So my question: is there a better way than pImpl to "augment" the pugixml library? And if so - how would you (@zeux) go about that? My assumption is that - even if pugixml is extended by the functions that I need for OpenXLSX - it will take months if not years to make its way into linux distro packages, so that I wouldn't gain much by depending on a very new pugixml library version. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
I don't really understand why there would be conflicts with pugixml that's externally packaged if you inherit from pugixml classes. It would seem like things should work just fine unless you are changing pugixml header/source file; if you aren't, I don't think pimpl will help here. But regardless, the only two reasonably clean options for class extension I know of are either inheritance, which you tried, or external free functions (which you can define in your own header, and put in either the common namespace in your application or even in pugi:: namespace to take advantage of argument dependent lookup). So you'd have something like I always prefer the latter, as it's cleaner and doesn't suffer from accidental object slicing that may change behavior (e.g. using an inherited API on xml_node that wasn't shadowed would return pugi::xml_node, and calling child on that would use the original method) - because every call is explicit. It's also way simpler as you don't need to duplicate functionality just for the sake of forwarding the calls. |
Beta Was this translation helpful? Give feedback.
As I noted in my previous comments, exposing internal details is a problem for binary (and interface) compatibility, so no, I'm not willing to do that.
I've looked at OpenXSLSX source briefly and I don't fully understand why "by type" functionality is particularly interesting; a few loops of that nature seem like they could just be replaced by the usual iterations without changing the semantics. When that's not the case, I'm very skeptical that a single call to
.type()
in the loop body per iteration is material for performance on top of everything else that happens in the code. In principle I'm not opposed to some sort of addition there if it's minimal, but I don't fully understand the us…