[libxml++] Re: [Libxmlplusplus-general] Adding STL-container-like methods to Node instead of returning a container instance

On Thu, Feb 06, 2003 at 05:08:02PM +0100, Murray Cumming wrote:

> On Tue, 2003-02-04 at 08:21, Stefan Seefeld wrote:
> > * enhance the tree manipulation API, adding a Node::child_iterator
> >    type, as well as new 'insert_child', and 'append_child' methods
> >    (in accordance with the usual STL nomenclature)
> Why is this necessary/desirable? I'm concerned that, if we decide to
> make xmlpp::Node look like std::list or std::vector, we should add _all_
> of the common STL-container methods. For instance, we should add a
> reverse iterator, and the front() and back() methods. Then lots of
> STL-container-like methods will be mixed up with the Node-specific
> methods and it won't be clear what is meant to be used for what
> functionality. And we might have made the API bigger and less clear
> without adding functionality.

I don't think this is a valid concern. The STL has several concepts of
container (which the C++ standard reuses) with increasingly restrictive
requirements, but the simplest ones (e.g. Container, Forward Container,
Sequence) have very few requirements. The Iterator concept is used
throughout the STL because it is valid for all container types, hiding
the actual implemntation of the container. The Sequence concept is a
good match for a DOM tree IMHO, and Sequences are not required to
support reverse iterator (that would be a Reversable Container) and
don't have to support back(). front() is required but that is no more
complex to implement than begin(), and it makes sense to be able to
access the first node of a doc directly and in constant time.
The SGI STL docs contain excellent descriptions of the various container
concepts and their requirements:

> I see that you have tried to avoid this by using method names such as
> children_begin() instead of begin() but then I think it's less
> STL-container-like.

IMHO this should be avoided, if the interface is vaguely STL-like then
it should conform properly to the STL interface (which defines common
names for the methods) otherwise users will expect it to match their
expectations and be surprised/annoyed by differences.

If the interface conforms fully to the STL concept of a Sequence then it
can be documented as such, and users can know _exactly_ what to expect
and what not to expect in terms of complexity guarantees. Conforming to
the STL concept of a Sequence does not require conformance to std::list
or any other standard type.

> If it's absolutely necessary then maybe we could consider an auxillary
> object, just to separate that part of the API.
> For instance,
> NodeChildren& nodeChildren = node.children();
> for(NodeChildren::iterator iter = nodeChildren.begin(), iter !=
> nodeChildren.end(); ++iter)
> {
>    ...
> }
> We do this, fairly successfully, with some gtkmm classes. But it's not
> ideal.

Maybe the iterator should only be available from the Document object,
giving access to all children, not available on each Node. This
corresponds to a std::Vector<Foo> having an iterator type, but not a
Foo. Given a Foo (which may or may not be contained in a vector) there
is no way to get an iterator for "all successive Foos", you can only get
an iterator from the containing object. Although in the DOM nodes can
be parents and/or children, in STL terms the nodes are all siblings, and
the container is the parent.

So it would be something like:

Document doc = //...
for (Document::iterator i=doc.begin(), toofar=doc.end(); i!=toofar; ++i)
    // ...


"If all these sweet young things were laid end to end,
 I wouldn't be the slightest bit surprised."
	- Dorothy Parker on Co-Eds

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]