Hamish Mackenzie wrote:

That way I'v got a pointer from the C struct to the C++ wrapper
(_private), as well as a pointer from the C++ wrapper to the C struct
(my_impl).


Would a thin proxy object not be a better way to go?  More in keeping
with the "you don't pay for what you don't use" philosophy of C++.

Hmm, I see your point. Well, that would be possible, but that way you
are unable to make nodes polymorphic. Neither with respect to the basic
node types (Element, Attribute, Text, CData, etc.) nor later when implementing real DOM support on top of it.


I have attached the wrappers I have written.  They do not cover much of
libxml2 (just what I needed at the time).  Feel free to borrow as much
or as little from it as you like.

yeah, looks interesting, and even more thin than my wrapper. However, the thinner the wrapper gets the greater is indeed the danger of having the whole design tied to a particular implementation, as William pointed out earlier. I don't think that this is a problem with my wrapper lib, but with your implementation you get dangerously close...:-)

If you look in node_iterator.h you can see that it uses a proxy
containing just a pointer to the libxml2 node.

indeed.


Looking up this node's parent node is thus simply

static_cast<Node *>(this->my_impl->parent->_private);


If there was a parent lookup in node_proxy it would be

class node_proxy
{
public:
  node_proxy parent() { return node_proxy( node_->parent ); }
...
private:
  xmlNodePtr node_;
};

yes, and you could even make that an 'element_proxy' as you know that parent nodes are always elements. However, with a flat set of (libxml2) nodes that wouldn't work any more, so runtime polymorphism would be lost. Well, may be there is no need for it either. I have to think over that...

making 'parse_file' a class suggests it is carrying some data/state.
What would that be ? I'm thinking of 'parse_file' as a stateless
factory, i.e. a function returning a newly created document.


Sorry I should have included the ... bit

class parse_file
{
public:
parse_file( const std::string & f ) : file_name_ {}
private:
const std::string & file_name_;
template< ... >
friend class ::boost::xml::dom::document;
};


Put that together with the constructor...

template<...>
class basic_document
{
public:
  basic_document( const parse_file & f )
  {
    // does what parse_file function does now
  }
};

And you can write code that goes

xml::dom::document doc( xml::dom::parse_file( "a.xml" ) );

No auto_ptr needed.  It's not in my wrappers as I only thought of it
while I was reading through yours.

well, but you could also make it such that


xml::dom::document doc = xml::dom::parse_file("a.xml");

works with parse_file being a function. That would mean the document is
copied, but then following your philosophy xml::dom::document could be
a proxy, too, so copying could be cheap...

I really don't like the idea of 'parse_file' being an object (whichs
state being a potentially already parsed document). It's unintuive.

parse_stream would indeed be even better.  As I recall there are
functions in libxml2 that allow you to write to the parser as well.

erm, that's even more confusing, I think. A parser should remain just a parser, i.e. something that extracts tokens from an input stream.

Best regards,
                Stefan

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

Reply via email to