Hamish Mackenzie wrote:

Why should the node-wrappers keep the document alive?

for consistency, and convenience. In the same way you can get down from the document to the individual nodes you can get up: node.parent() and node.document() provide the means to walk up towards the document root.

node.begin_children() lets you iterate over all current child nodes,
i.e. the nodes it returns will all be valid, thus this iterator
interface is as stable as that of linked lists.
I expect the same from node.parent() and node.document(), i.e. as long
as there is an API to walk the tree, it should return valid objects.

That is not to say that these objects will remain valid over time.
As you point out, erasing the content of a container will invalidate
iterators you may still hold for that container.

Imagine a factory object that is initialized with a dom::node_ptr
(holding configurational data, say). Whenever you access its method,
the object looks up data in the node...


class factory { public: factory(dom::node_ptr n) : my_node(n) {} foo create_foo(); /* access my_node */ bar create_bar(); /* access my_node */ private: dom::node_ptr my_node; };

factory 'owns' the node, so whereever you instantiate the factory,
you'd read in a dom::document, look up the relevant node, and pass
that to the constructor:

factory *f;
{
  dom::document_ptr document("config.xml");
  dom::node_set set = document.root_node().find("//factory.info");
  f = new factory(set[0]);
} // document and set are now deleted, but factory still references
  // the document through its 'my_node' member


If the document wasn't ref-counted, you'd need to pass it along with the node to the factory, as only the factory would know when to drop it (in its destructor, presumably).


Here is the analogy I think works best...

container --> document
container::value_type --> node
container::iterator --> node_iterator
container::pointer_type --> node_pointer
container::reference_type --> node_reference

hmm, that makes it look simpler than it actually is: is there really a single 'value_type' ? Is there really a single iterator ? (iterating over all child nodes of a given parent and iterating over all attributes is not the same) Also, what is a node_reference (as opposed to a pointer) ?

Consider the following....

std::vector< foo > x;
...
foo * y = &x[0];
x.erase( x.begin(), x.end() );

I don't expect y to add_ref x.  I wouldn't mind if it did, but it
wouldn't make y any more valid after the call to erase.

agreed. However, you explicitely erase elements, while all I want to prevent is implicit object destruction just because a reference to it
goes out of scope.


So the problem with add reffing the document is... what happens if the
root node or some parent of a node you have a pointer to is erased from
the document?  libxml2 has no way of knowing you have a pointer to a
child node.

that's right. And adding such a feature may be quite expensive memory / performance wise. As I said, I don't feel it's a problem, as you would
explicitely remove the node, so you should know what you are doing anyways. (As you said, you wouldn't even expect an iterator to be valid
after you erase the container's content).


Regards,
                Stefan

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to