summaryrefslogtreecommitdiff
path: root/libxsd/xsd/cxx/tree/containers-wildcard.hxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-09-17 07:15:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-09-17 07:15:29 +0200
commitf0510d2f90467de8e8f260b47d79a9baaf9bef17 (patch)
tree0b9929946f06a9cbe9b9e8f2a7600dae4e048f79 /libxsd/xsd/cxx/tree/containers-wildcard.hxx
Start tracking XSD with git
Diffstat (limited to 'libxsd/xsd/cxx/tree/containers-wildcard.hxx')
-rw-r--r--libxsd/xsd/cxx/tree/containers-wildcard.hxx1335
1 files changed, 1335 insertions, 0 deletions
diff --git a/libxsd/xsd/cxx/tree/containers-wildcard.hxx b/libxsd/xsd/cxx/tree/containers-wildcard.hxx
new file mode 100644
index 0000000..53c0d22
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/containers-wildcard.hxx
@@ -0,0 +1,1335 @@
+// file : xsd/cxx/tree/containers-wildcard.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
+#define XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
+
+#include <set>
+#include <string>
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/util/XMLString.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+
+#include <xsd/cxx/tree/containers.hxx> // iterator_adapter
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // one (for internal use only)
+ //
+ class element_one
+ {
+ public:
+ ~element_one ()
+ {
+ if (x_)
+ x_->release ();
+ }
+
+ explicit
+ element_one (xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ }
+
+ element_one (const xercesc::DOMElement& x, xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ set (x);
+ }
+
+ element_one (const element_one& x, xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ if (x.present ())
+ set (x.get ());
+ }
+
+ element_one&
+ operator= (const element_one& x)
+ {
+ if (this == &x)
+ return *this;
+
+ if (x.present ())
+ set (x.get ());
+ else if (x_)
+ {
+ x_->release ();
+ x_ = 0;
+ }
+
+ return *this;
+ }
+
+ public:
+ const xercesc::DOMElement&
+ get () const
+ {
+ return *x_;
+ }
+
+ xercesc::DOMElement&
+ get ()
+ {
+ return *x_;
+ }
+
+ void
+ set (const xercesc::DOMElement& x)
+ {
+ using xercesc::DOMElement;
+
+ DOMElement* r (
+ static_cast<DOMElement*> (
+ doc_.importNode (const_cast<DOMElement*> (&x), true)));
+
+ if (x_)
+ x_->release ();
+
+ x_ = r;
+ }
+
+ void
+ set (xercesc::DOMElement* x)
+ {
+ assert (x->getOwnerDocument () == &doc_);
+
+ if (x_)
+ x_->release ();
+
+ x_ = x;
+ }
+
+ bool
+ present () const
+ {
+ return x_ != 0;
+ }
+
+ protected:
+ xercesc::DOMElement* x_;
+ xercesc::DOMDocument& doc_;
+ };
+
+
+ //
+ //
+ class element_optional
+ {
+ public:
+ ~element_optional ()
+ {
+ if (x_)
+ x_->release ();
+ }
+
+ explicit
+ element_optional (xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ }
+
+ element_optional (const xercesc::DOMElement& x,
+ xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ set (x);
+ }
+
+ element_optional (xercesc::DOMElement* x, xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ set (x);
+ }
+
+ element_optional (const element_optional& x,
+ xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ if (x)
+ set (*x);
+ }
+
+ element_optional&
+ operator= (const xercesc::DOMElement& x)
+ {
+ if (x_ == &x)
+ return *this;
+
+ set (x);
+
+ return *this;
+ }
+
+ element_optional&
+ operator= (const element_optional& x)
+ {
+ if (this == &x)
+ return *this;
+
+ if (x)
+ set (*x);
+ else
+ reset ();
+
+ return *this;
+ }
+
+ // Pointer-like interface.
+ //
+ public:
+ const xercesc::DOMElement*
+ operator-> () const
+ {
+ return x_;
+ }
+
+ xercesc::DOMElement*
+ operator-> ()
+ {
+ return x_;
+ }
+
+ const xercesc::DOMElement&
+ operator* () const
+ {
+ return *x_;
+ }
+
+ xercesc::DOMElement&
+ operator* ()
+ {
+ return *x_;
+ }
+
+ typedef void (element_optional::*bool_convertible) ();
+
+ operator bool_convertible () const
+ {
+ return x_ != 0 ? &element_optional::true_ : 0;
+ }
+
+ // Get/set interface.
+ //
+ public:
+ bool
+ present () const
+ {
+ return x_ != 0;
+ }
+
+ const xercesc::DOMElement&
+ get () const
+ {
+ return *x_;
+ }
+
+ xercesc::DOMElement&
+ get ()
+ {
+ return *x_;
+ }
+
+ void
+ set (const xercesc::DOMElement& x)
+ {
+ using xercesc::DOMElement;
+
+ DOMElement* r (
+ static_cast<DOMElement*> (
+ doc_.importNode (const_cast<DOMElement*> (&x), true)));
+
+ if (x_)
+ x_->release ();
+
+ x_ = r;
+ }
+
+ void
+ set (xercesc::DOMElement* x)
+ {
+ assert (x->getOwnerDocument () == &doc_);
+
+ if (x_)
+ x_->release ();
+
+ x_ = x;
+ }
+
+ void
+ reset ()
+ {
+ if (x_)
+ x_->release ();
+
+ x_ = 0;
+ }
+
+ private:
+ void
+ true_ ()
+ {
+ }
+
+ private:
+ xercesc::DOMElement* x_;
+ xercesc::DOMDocument& doc_;
+ };
+
+ // Comparison operators.
+ //
+
+ inline bool
+ operator== (const element_optional& a, const element_optional& b)
+ {
+ return !a || !b
+ ? a.present () == b.present ()
+ : a->isEqualNode (&b.get ());
+ }
+
+ inline bool
+ operator!= (const element_optional& a, const element_optional& b)
+ {
+ return !(a == b);
+ }
+
+
+ //
+ //
+ class element_sequence
+ {
+ protected:
+ // This is a dangerously destructive automatic pointer. We are going
+ // to use it in a controlled environment to save us a lot of coding.
+ //
+ struct ptr
+ {
+ ~ptr ()
+ {
+ if (x_)
+ x_->release ();
+ }
+
+ explicit
+ ptr (xercesc::DOMElement* x = 0)
+ : x_ (x)
+ {
+ }
+
+ ptr (const ptr& y)
+ : x_ (y.x_)
+ {
+ // Yes, hostile takeover.
+ //
+ y.x_ = 0;
+ }
+
+ ptr&
+ operator= (const ptr& y)
+ {
+ if (this != &y)
+ {
+ // Yes, hostile takeover.
+ //
+ if (x_)
+ x_->release ();
+
+ x_ = y.x_;
+ y.x_ = 0;
+ }
+
+ return *this;
+ }
+
+ public:
+ xercesc::DOMElement&
+ operator* () const
+ {
+ return *x_;
+ }
+
+ xercesc::DOMElement*
+ get () const
+ {
+ return x_;
+ }
+
+ private:
+ mutable xercesc::DOMElement* x_;
+ };
+
+ typedef std::vector<ptr> base_sequence;
+ typedef base_sequence::iterator base_iterator;
+ typedef base_sequence::const_iterator base_const_iterator;
+
+ public:
+ typedef xercesc::DOMElement value_type;
+ typedef xercesc::DOMElement* pointer;
+ typedef const xercesc::DOMElement* const_pointer;
+ typedef xercesc::DOMElement& reference;
+ typedef const xercesc::DOMElement& const_reference;
+
+ typedef
+ iterator_adapter<base_sequence::iterator, xercesc::DOMElement>
+ iterator;
+
+ typedef
+ iterator_adapter<base_sequence::const_iterator,
+ const xercesc::DOMElement>
+ const_iterator;
+
+ typedef
+ iterator_adapter<base_sequence::reverse_iterator, xercesc::DOMElement>
+ reverse_iterator;
+
+ typedef
+ iterator_adapter<base_sequence::const_reverse_iterator,
+ const xercesc::DOMElement>
+ const_reverse_iterator;
+
+ typedef base_sequence::size_type size_type;
+ typedef base_sequence::difference_type difference_type;
+ typedef base_sequence::allocator_type allocator_type;
+
+ public:
+ explicit
+ element_sequence (xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ }
+
+ // DOMElement cannot be default-constructed.
+ //
+ // explicit
+ // element_sequence (size_type n);
+
+ element_sequence (size_type n,
+ const xercesc::DOMElement& x,
+ xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ assign (n, x);
+ }
+
+ template <typename I>
+ element_sequence (const I& begin, const I& end,
+ xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ assign (begin, end);
+ }
+
+ element_sequence (const element_sequence& v,
+ xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ v_.reserve (v.v_.size ());
+
+ for (base_const_iterator i (v.v_.begin ()), e (v.v_.end ());
+ i != e; ++i)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (i->get (), true)));
+
+ v_.push_back (p);
+ }
+ }
+
+ element_sequence&
+ operator= (const element_sequence& v)
+ {
+ if (this == &v)
+ return *this;
+
+ v_.assign (v.v_.size (), ptr ());
+
+ base_iterator di (v_.begin ()), de (v_.end ());
+ base_const_iterator si (v.v_.begin ()), se (v.v_.end ());
+
+ for (; si != se && di != de; ++si, ++di)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (si->get (), true)));
+ *di = p;
+ }
+
+ return *this;
+ }
+
+ public:
+ void
+ assign (size_type n, const xercesc::DOMElement& x)
+ {
+ v_.assign (n, ptr ());
+
+ for (base_iterator i (v_.begin ()), e (v_.end ()); i != e; ++i)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+ *i = p;
+ }
+ }
+
+ template <typename I>
+ void
+ assign (const I& begin, const I& end)
+ {
+ // This is not the fastest way to do it.
+ //
+ v_.clear ();
+
+ for (I i (begin); i != end; ++i)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&(*i)), true)));
+ v_.push_back (p);
+ }
+ }
+
+ public:
+ // This version of resize can only be used to shrink the
+ // sequence because DOMElement cannot be default-constructed.
+ //
+ void
+ resize (size_type n)
+ {
+ assert (n <= v_.size ());
+ v_.resize (n, ptr ());
+ }
+
+ void
+ resize (size_type n, const xercesc::DOMElement& x)
+ {
+ size_type old (v_.size ());
+ v_.resize (n, ptr ());
+
+ if (old < n)
+ {
+ for (base_iterator i (v_.begin () + old), e (v_.end ());
+ i != e; ++i)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+ *i = p;
+ }
+ }
+ }
+
+ public:
+ size_type
+ size () const
+ {
+ return v_.size ();
+ }
+
+ size_type
+ max_size () const
+ {
+ return v_.max_size ();
+ }
+
+ size_type
+ capacity () const
+ {
+ return v_.capacity ();
+ }
+
+ bool
+ empty () const
+ {
+ return v_.empty ();
+ }
+
+ void
+ reserve (size_type n)
+ {
+ v_.reserve (n);
+ }
+
+ void
+ clear ()
+ {
+ v_.clear ();
+ }
+
+ public:
+ const_iterator
+ begin () const
+ {
+ return const_iterator (v_.begin ());
+ }
+
+ const_iterator
+ end () const
+ {
+ return const_iterator (v_.end ());
+ }
+
+ iterator
+ begin ()
+ {
+ return iterator (v_.begin ());
+ }
+
+ iterator
+ end ()
+ {
+ return iterator (v_.end ());
+ }
+
+ // reverse
+ //
+
+ const_reverse_iterator
+ rbegin () const
+ {
+ return const_reverse_iterator (v_.rbegin ());
+ }
+
+ const_reverse_iterator
+ rend () const
+ {
+ return const_reverse_iterator (v_.rend ());
+ }
+
+ reverse_iterator
+ rbegin ()
+ {
+ return reverse_iterator (v_.rbegin ());
+ }
+
+ reverse_iterator
+ rend ()
+ {
+ return reverse_iterator (v_.rend ());
+ }
+
+ public:
+ xercesc::DOMElement&
+ operator[] (size_type n)
+ {
+ return *(v_[n]);
+ }
+
+ const xercesc::DOMElement&
+ operator[] (size_type n) const
+ {
+ return *(v_[n]);
+ }
+
+ xercesc::DOMElement&
+ at (size_type n)
+ {
+ return *(v_.at (n));
+ }
+
+ const xercesc::DOMElement&
+ at (size_type n) const
+ {
+ return *(v_.at (n));
+ }
+
+ xercesc::DOMElement&
+ front ()
+ {
+ return *(v_.front ());
+ }
+
+ const xercesc::DOMElement&
+ front () const
+ {
+ return *(v_.front ());
+ }
+
+ xercesc::DOMElement&
+ back ()
+ {
+ return *(v_.back ());
+ }
+
+ const xercesc::DOMElement&
+ back () const
+ {
+ return *(v_.back ());
+ }
+
+ public:
+ // Makes a deep copy.
+ //
+ void
+ push_back (const xercesc::DOMElement& x)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+
+ v_.push_back (p);
+ }
+
+ // Assumes ownership.
+ //
+ void
+ push_back (xercesc::DOMElement* x)
+ {
+ assert (x->getOwnerDocument () == &doc_);
+ v_.push_back (ptr (x));
+ }
+
+ void
+ pop_back ()
+ {
+ v_.pop_back ();
+ }
+
+ // Makes a deep copy.
+ //
+ iterator
+ insert (iterator position, const xercesc::DOMElement& x)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+
+ return iterator (v_.insert (position.base (), p));
+ }
+
+ // Assumes ownership.
+ //
+ iterator
+ insert (iterator position, xercesc::DOMElement* x)
+ {
+ assert (x->getOwnerDocument () == &doc_);
+ return iterator (v_.insert (position.base (), ptr (x)));
+ }
+
+ void
+ insert (iterator position, size_type n, const xercesc::DOMElement& x)
+ {
+ difference_type d (v_.end () - position.base ());
+ v_.insert (position.base (), n, ptr ());
+
+ for (base_iterator i (v_.end () - d); n != 0; --n)
+ {
+ ptr r (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+ *(--i) = r;
+ }
+ }
+
+ template <typename I>
+ void
+ insert (iterator position, const I& begin, const I& end)
+ {
+ // This is not the fastest way to do it.
+ //
+ if (begin != end)
+ {
+ base_iterator p (position.base ());
+
+ for (I i (end);;)
+ {
+ --i;
+ ptr r (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (i->get (), true)));
+
+ p = v_.insert (p, r);
+
+ if (i == begin)
+ break;
+ }
+ }
+ }
+
+ iterator
+ erase (iterator position)
+ {
+ return iterator (v_.erase (position.base ()));
+ }
+
+ iterator
+ erase (iterator begin, iterator end)
+ {
+ return iterator (v_.erase (begin.base (), end.base ()));
+ }
+
+ public:
+ // Note that the DOMDocument object of the two sequences being
+ // swapped should be the same.
+ //
+ void
+ swap (element_sequence& x)
+ {
+ assert (&doc_ == &x.doc_);
+ v_.swap (x.v_);
+ }
+
+ private:
+ base_sequence v_;
+ xercesc::DOMDocument& doc_;
+ };
+
+ // Comparison operators.
+ //
+
+ inline bool
+ operator== (const element_sequence& a, const element_sequence& b)
+ {
+ if (a.size () != b.size ())
+ return false;
+
+ element_sequence::const_iterator
+ ai (a.begin ()), ae (a.end ()), bi (b.begin ());
+
+ for (; ai != ae; ++ai, ++bi)
+ if (!ai->isEqualNode (&(*bi)))
+ return false;
+
+ return true;
+ }
+
+ inline bool
+ operator!= (const element_sequence& a, const element_sequence& b)
+ {
+ return !(a == b);
+ }
+
+
+ // Attribute set.
+ //
+
+ class attribute_set_common
+ {
+ protected:
+ // Set entry. It can either act as a dangerously destructive
+ // automatic pointer for DOMAttr or as an entry containing the
+ // name we are searching for.
+ //
+ struct entry
+ {
+ ~entry ()
+ {
+ if (a_)
+ a_->release ();
+ }
+
+ explicit
+ entry (xercesc::DOMAttr* a)
+ : a_ (a), ns_ (0), name_ (0)
+ {
+ ns_ = a->getNamespaceURI ();
+ name_ = ns_ == 0 ? a->getName () : a->getLocalName ();
+ }
+
+ // Note: uses shallow copy.
+ //
+ explicit
+ entry (const XMLCh* ns, const XMLCh* name)
+ : a_ (0), ns_ (ns), name_ (name)
+ {
+ }
+
+ entry (const entry& y)
+ : a_ (y.a_), ns_ (y.ns_), name_ (y.name_)
+ {
+ // Yes, hostile takeover.
+ //
+ y.a_ = 0;
+ y.ns_ = 0;
+ y.name_ = 0;
+ }
+
+ entry&
+ operator= (const entry& y)
+ {
+ if (this != &y)
+ {
+ // Yes, hostile takeover.
+ //
+ if (a_)
+ a_->release ();
+
+ a_ = y.a_;
+ ns_ = y.ns_;
+ name_ = y.name_;
+
+ y.a_ = 0;
+ y.ns_ = 0;
+ y.name_ = 0;
+ }
+
+ return *this;
+ }
+
+ public:
+ xercesc::DOMAttr&
+ operator* () const
+ {
+ return *a_;
+ }
+
+ xercesc::DOMAttr*
+ get () const
+ {
+ return a_;
+ }
+
+ const XMLCh*
+ ns () const
+ {
+ return ns_;
+ }
+
+ const XMLCh*
+ name () const
+ {
+ return name_;
+ }
+
+ void
+ release ()
+ {
+ a_ = 0;
+ }
+
+ private:
+ mutable xercesc::DOMAttr* a_;
+ mutable const XMLCh* ns_;
+ mutable const XMLCh* name_;
+ };
+
+ struct entry_cmp
+ {
+ bool
+ operator() (const entry& a, const entry& b) const
+ {
+ using xercesc::XMLString;
+
+ const XMLCh* ans (a.ns ());
+ const XMLCh* bns (b.ns ());
+
+ const XMLCh* an (a.name ());
+ const XMLCh* bn (b.name ());
+
+ if (ans == 0)
+ return bns != 0
+ ? true
+ : (XMLString::compareString (an, bn) < 0);
+
+ if (ans != 0 && bns == 0)
+ return false;
+
+ int r (XMLString::compareString (ans, bns));
+
+ return r < 0
+ ? true
+ : (r > 0 ? false : XMLString::compareString (an, bn));
+ }
+ };
+
+ typedef std::set<entry, entry_cmp> base_set;
+ typedef base_set::iterator base_iterator;
+ typedef base_set::const_iterator base_const_iterator;
+ };
+
+ template <typename C>
+ class attribute_set: public attribute_set_common
+ {
+ public:
+ typedef xercesc::DOMAttr key_type;
+ typedef xercesc::DOMAttr value_type;
+ typedef xercesc::DOMAttr* pointer;
+ typedef const xercesc::DOMAttr* const_pointer;
+ typedef xercesc::DOMAttr& reference;
+ typedef const xercesc::DOMAttr& const_reference;
+
+ typedef
+ iterator_adapter<base_set::iterator, xercesc::DOMAttr>
+ iterator;
+
+ typedef
+ iterator_adapter<base_set::const_iterator, const xercesc::DOMAttr>
+ const_iterator;
+
+ typedef
+ iterator_adapter<base_set::reverse_iterator, xercesc::DOMAttr>
+ reverse_iterator;
+
+ typedef
+ iterator_adapter<base_set::const_reverse_iterator,
+ const xercesc::DOMAttr>
+ const_reverse_iterator;
+
+ typedef base_set::size_type size_type;
+ typedef base_set::difference_type difference_type;
+ typedef base_set::allocator_type allocator_type;
+
+ public:
+ attribute_set (xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ }
+
+ template <typename I>
+ attribute_set (const I& begin,
+ const I& end,
+ xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ insert (begin, end);
+ }
+
+ attribute_set (const attribute_set& s, xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ // Can be done faster with the "hinted" insert.
+ //
+ insert (s.begin (), s.end ());
+ }
+
+ attribute_set&
+ operator= (const attribute_set& s)
+ {
+ if (this == &s)
+ return *this;
+
+ // Can be done faster with the "hinted" insert.
+ //
+ clear ();
+ insert (s.begin (), s.end ());
+
+ return *this;
+ }
+
+ public:
+ const_iterator
+ begin () const
+ {
+ return const_iterator (s_.begin ());
+ }
+
+ const_iterator
+ end () const
+ {
+ return const_iterator (s_.end ());
+ }
+
+ iterator
+ begin ()
+ {
+ return iterator (s_.begin ());
+ }
+
+ iterator
+ end ()
+ {
+ return iterator (s_.end ());
+ }
+
+ // reverse
+ //
+
+ const_reverse_iterator
+ rbegin () const
+ {
+ return const_reverse_iterator (s_.rbegin ());
+ }
+
+ const_reverse_iterator
+ rend () const
+ {
+ return const_reverse_iterator (s_.rend ());
+ }
+
+ reverse_iterator
+ rbegin ()
+ {
+ return reverse_iterator (s_.rbegin ());
+ }
+
+ reverse_iterator
+ rend ()
+ {
+ return reverse_iterator (s_.rend ());
+ }
+
+ public:
+ size_type
+ size () const
+ {
+ return s_.size ();
+ }
+
+ size_type
+ max_size () const
+ {
+ return s_.max_size ();
+ }
+
+ bool
+ empty () const
+ {
+ return s_.empty ();
+ }
+
+ void
+ clear ()
+ {
+ s_.clear ();
+ }
+
+ public:
+ // Makes a deep copy.
+ //
+ std::pair<iterator, bool>
+ insert (const xercesc::DOMAttr& a)
+ {
+ entry e (static_cast<xercesc::DOMAttr*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMAttr*> (&a), true)));
+
+ std::pair<base_iterator, bool> r (s_.insert (e));
+
+ return std::pair<iterator, bool> (iterator (r.first), r.second);
+ }
+
+ // Assumes ownership.
+ //
+ std::pair<iterator, bool>
+ insert (xercesc::DOMAttr* a)
+ {
+ assert (a->getOwnerDocument () == &doc_);
+ entry e (a);
+ std::pair<base_iterator, bool> r (s_.insert (e));
+
+ if (!r.second)
+ e.release (); // Detach the attribute of insert failed.
+
+ return std::pair<iterator, bool> (iterator (r.first), r.second);
+ }
+
+ // Makes a deep copy.
+ //
+ iterator
+ insert (iterator position, const xercesc::DOMAttr& a)
+ {
+ entry e (static_cast<xercesc::DOMAttr*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMAttr*> (&a), true)));
+
+ return iterator (s_.insert (position.base (), e));
+ }
+
+ // Assumes ownership.
+ //
+ iterator
+ insert (iterator position, xercesc::DOMAttr* a)
+ {
+ assert (a->getOwnerDocument () == &doc_);
+ entry e (a);
+ base_iterator r (s_.insert (position.base (), e));
+
+ if (r->get () != a)
+ e.release (); // Detach the attribute of insert failed.
+
+ return iterator (r);
+ }
+
+ template <typename I>
+ void
+ insert (const I& begin, const I& end)
+ {
+ for (I i (begin); i != end; ++i)
+ {
+ entry e (static_cast<xercesc::DOMAttr*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMAttr*> (&(*i)), true)));
+
+ s_.insert (e);
+ }
+ }
+
+ public:
+ void
+ erase (iterator position)
+ {
+ s_.erase (position.base ());
+ }
+
+ size_type
+ erase (const std::basic_string<C>& name)
+ {
+ return s_.erase (entry (0, xml::string (name).c_str ()));
+ }
+
+ size_type
+ erase (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& name)
+ {
+ return s_.erase (entry (xml::string (namespace_).c_str (),
+ xml::string (name).c_str ()));
+ }
+
+ size_type
+ erase (const XMLCh* name)
+ {
+ return s_.erase (entry (0, name));
+ }
+
+ size_type
+ erase (const XMLCh* namespace_, const XMLCh* name)
+ {
+ return s_.erase (entry (namespace_, name));
+ }
+
+ void
+ erase (iterator begin, iterator end)
+ {
+ s_.erase (begin.base (), end.base ());
+ }
+
+ public:
+ size_type
+ count (const std::basic_string<C>& name) const
+ {
+ return s_.count (entry (0, xml::string (name).c_str ()));
+ }
+
+ size_type
+ count (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& name) const
+ {
+ return s_.count (entry (xml::string (namespace_).c_str (),
+ xml::string (name).c_str ()));
+ }
+
+ size_type
+ count (const XMLCh* name) const
+ {
+ return s_.count (entry (0, name));
+ }
+
+ size_type
+ count (const XMLCh* namespace_, const XMLCh* name) const
+ {
+ return s_.count (entry (namespace_, name));
+ }
+
+ // find
+ //
+
+ iterator
+ find (const std::basic_string<C>& name)
+ {
+ return iterator (s_.find (entry (0, xml::string (name).c_str ())));
+ }
+
+ iterator
+ find (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& name)
+ {
+ return iterator (
+ s_.find (entry (xml::string (namespace_).c_str (),
+ xml::string (name).c_str ())));
+ }
+
+ iterator
+ find (const XMLCh* name)
+ {
+ return iterator (s_.find (entry (0, name)));
+ }
+
+ iterator
+ find (const XMLCh* namespace_, const XMLCh* name)
+ {
+ return iterator (s_.find (entry (namespace_, name)));
+ }
+
+ const_iterator
+ find (const std::basic_string<C>& name) const
+ {
+ return const_iterator (
+ s_.find (entry (0, xml::string (name).c_str ())));
+ }
+
+ const_iterator
+ find (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& name) const
+ {
+ return const_iterator (
+ s_.find (entry (xml::string (namespace_).c_str (),
+ xml::string (name).c_str ())));
+ }
+
+ const_iterator
+ find (const XMLCh* name) const
+ {
+ return const_iterator (s_.find (entry (0, name)));
+ }
+
+ const_iterator
+ find (const XMLCh* namespace_, const XMLCh* name) const
+ {
+ return const_iterator (s_.find (entry (namespace_, name)));
+ }
+
+ public:
+ // Note that the DOMDocument object of the two sets being
+ // swapped should be the same.
+ //
+ void
+ swap (attribute_set& x)
+ {
+ assert (&doc_ == &x.doc_);
+ s_.swap (x.s_);
+ }
+
+ private:
+ base_set s_;
+ xercesc::DOMDocument& doc_;
+ };
+
+ // Comparison operators.
+ //
+
+ template <typename C>
+ inline bool
+ operator== (const attribute_set<C>& a, const attribute_set<C>& b)
+ {
+ if (a.size () != b.size ())
+ return false;
+
+ typename attribute_set<C>::const_iterator
+ ai (a.begin ()), ae (a.end ()), bi (b.begin ());
+
+ for (; ai != ae; ++ai, ++bi)
+ if (!ai->isEqualNode (&(*bi)))
+ return false;
+
+ return true;
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const attribute_set<C>& a, const attribute_set<C>& b)
+ {
+ return !(a == b);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX